185 lines
5.0 KiB
Vue
185 lines
5.0 KiB
Vue
<script setup lang="ts">
|
|
import AuthProvider from "@/views/pages/authentication/AuthProvider.vue";
|
|
import logo from "@images/logo.svg?raw";
|
|
import authV1BottomShape from "@images/svg/auth-v1-bottom-shape.svg?url";
|
|
import authV1TopShape from "@images/svg/auth-v1-top-shape.svg?url";
|
|
|
|
const form = ref({
|
|
user_id: "",
|
|
password: "",
|
|
remember: false,
|
|
});
|
|
|
|
const isPasswordVisible = ref(false);
|
|
const isLoading = ref(false);
|
|
const errorMessage = ref("");
|
|
|
|
const router = useRouter();
|
|
|
|
// 컴포넌트 마운트 시 테스트
|
|
onMounted(() => {});
|
|
|
|
const handleLogin = async () => {
|
|
if (!form.value.user_id || !form.value.password) {
|
|
errorMessage.value = "아이디와 비밀번호를 입력해주세요.";
|
|
return;
|
|
}
|
|
|
|
isLoading.value = true;
|
|
errorMessage.value = "";
|
|
|
|
try {
|
|
const response = await $fetch("/api/auth/login", {
|
|
method: "POST",
|
|
body: {
|
|
user_id: form.value.user_id,
|
|
password: form.value.password,
|
|
},
|
|
});
|
|
|
|
if (response.success) {
|
|
// 토큰을 쿠키에 저장
|
|
const token = useCookie("auth-token", {
|
|
maxAge: 60 * 60 * 24, // 24시간
|
|
secure: true,
|
|
sameSite: "strict",
|
|
});
|
|
token.value = response.token;
|
|
|
|
// 사용자 정보를 쿠키에 저장
|
|
const user = useCookie("user-info", {
|
|
maxAge: 60 * 60 * 24,
|
|
secure: true,
|
|
sameSite: "strict",
|
|
});
|
|
user.value = JSON.stringify(response.user);
|
|
|
|
// 대시보드로 리다이렉션
|
|
await router.push("/dashboard");
|
|
} else {
|
|
errorMessage.value = response.message || "로그인에 실패했습니다.";
|
|
}
|
|
} catch (error: any) {
|
|
console.error("Login error:", error);
|
|
console.error("Error details:", {
|
|
statusCode: error.statusCode,
|
|
statusMessage: error.statusMessage,
|
|
data: error.data,
|
|
});
|
|
errorMessage.value =
|
|
error.data?.statusMessage ||
|
|
error.statusMessage ||
|
|
"로그인 중 오류가 발생했습니다.";
|
|
} finally {
|
|
isLoading.value = false;
|
|
}
|
|
};
|
|
|
|
definePageMeta({
|
|
layout: "blank",
|
|
middleware: "guest",
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div class="auth-wrapper d-flex align-center justify-center pa-4">
|
|
<div class="position-relative my-sm-16">
|
|
<!-- 👉 Top shape -->
|
|
<VImg
|
|
:src="authV1TopShape"
|
|
class="text-primary auth-v1-top-shape d-none d-sm-block"
|
|
/>
|
|
|
|
<!-- 👉 Bottom shape -->
|
|
<VImg
|
|
:src="authV1BottomShape"
|
|
class="text-primary auth-v1-bottom-shape d-none d-sm-block"
|
|
/>
|
|
|
|
<!-- 👉 Auth Card -->
|
|
<VCard
|
|
class="auth-card"
|
|
max-width="460"
|
|
:class="$vuetify.display.smAndUp ? 'pa-6' : 'pa-0'"
|
|
>
|
|
<VCardItem class="justify-center">
|
|
<NuxtLink to="/" class="app-logo">
|
|
<!-- eslint-disable vue/no-v-html -->
|
|
<!-- <div
|
|
class="d-flex"
|
|
v-html="logo"
|
|
/>
|
|
<h1 class="app-logo-title">
|
|
sneat
|
|
</h1> -->
|
|
</NuxtLink>
|
|
</VCardItem>
|
|
|
|
<VCardText>
|
|
<h4 class="text-h4 mb-1">음악 관리 시스템👋🏻</h4>
|
|
<p class="mb-0">계정에 로그인하여 관리 시스템을 시작하세요</p>
|
|
</VCardText>
|
|
|
|
<VCardText>
|
|
<VForm @submit.prevent="handleLogin">
|
|
<VRow>
|
|
<!-- 오류 메시지 -->
|
|
<VCol v-if="errorMessage" cols="12">
|
|
<VAlert
|
|
type="error"
|
|
variant="tonal"
|
|
closable
|
|
@click:close="errorMessage = ''"
|
|
>
|
|
{{ errorMessage }}
|
|
</VAlert>
|
|
</VCol>
|
|
|
|
<!-- 아이디 -->
|
|
<VCol cols="12">
|
|
<VTextField
|
|
:id="useId()"
|
|
v-model="form.user_id"
|
|
autofocus
|
|
label="아이디"
|
|
placeholder="아이디를 입력하세요"
|
|
/>
|
|
</VCol>
|
|
|
|
<!-- 비밀번호 -->
|
|
<VCol cols="12">
|
|
<VTextField
|
|
:id="useId()"
|
|
v-model="form.password"
|
|
label="비밀번호"
|
|
placeholder="············"
|
|
:type="isPasswordVisible ? 'text' : 'password'"
|
|
autocomplete="password"
|
|
:append-inner-icon="isPasswordVisible ? 'bx-hide' : 'bx-show'"
|
|
@click:append-inner="isPasswordVisible = !isPasswordVisible"
|
|
/>
|
|
</VCol>
|
|
|
|
<VCol cols="12">
|
|
<VBtn
|
|
block
|
|
type="button"
|
|
:loading="isLoading"
|
|
:disabled="isLoading"
|
|
@click="handleLogin"
|
|
>
|
|
로그인
|
|
</VBtn>
|
|
</VCol>
|
|
</VRow>
|
|
</VForm>
|
|
</VCardText>
|
|
</VCard>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="scss">
|
|
@use "@core/scss/template/pages/page-auth";
|
|
</style>
|