146 lines
5.1 KiB
Svelte
146 lines
5.1 KiB
Svelte
<script lang="ts">
|
|
import { enhance } from '$app/forms';
|
|
import type { ActionData } from './$types';
|
|
import { Button } from '$lib/components/ui/button';
|
|
import { Input } from '$lib/components/ui/input';
|
|
import { Label } from '$lib/components/ui/label';
|
|
import * as Card from '$lib/components/ui/card';
|
|
import { Lock, User, LogIn, UserPlus, AlertCircle } from 'lucide-svelte';
|
|
|
|
let { form }: { form: ActionData } = $props();
|
|
</script>
|
|
|
|
<div class="relative flex min-h-screen items-center justify-center overflow-hidden p-4">
|
|
<!-- Fancy Animated Background -->
|
|
<div class="absolute inset-0 bg-gradient-to-br from-violet-500/5 via-background to-cyan-500/5"></div>
|
|
|
|
<!-- Animated Gradient Orbs -->
|
|
<div
|
|
class="absolute -left-40 -top-40 h-80 w-80 animate-pulse rounded-full bg-gradient-to-r from-purple-400/20 to-pink-600/20 blur-3xl"
|
|
style="animation-duration: 4s;"
|
|
></div>
|
|
<div
|
|
class="absolute -bottom-40 -right-40 h-80 w-80 animate-pulse rounded-full bg-gradient-to-r from-cyan-400/20 to-blue-600/20 blur-3xl"
|
|
style="animation-duration: 6s; animation-delay: 1s;"
|
|
></div>
|
|
<div
|
|
class="absolute left-1/2 top-1/2 h-96 w-96 -translate-x-1/2 -translate-y-1/2 animate-pulse rounded-full bg-gradient-to-r from-violet-400/10 to-fuchsia-600/10 blur-3xl"
|
|
style="animation-duration: 8s; animation-delay: 2s;"
|
|
></div>
|
|
|
|
<!-- Grid Pattern Overlay -->
|
|
<div
|
|
class="absolute inset-0 bg-[linear-gradient(to_right,#80808008_1px,transparent_1px),linear-gradient(to_bottom,#80808008_1px,transparent_1px)] bg-[size:24px_24px]"
|
|
></div>
|
|
|
|
<!-- Noise Texture -->
|
|
<div class="absolute inset-0 bg-[url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMDAiIGhlaWdodD0iMzAwIj48ZmlsdGVyIGlkPSJhIiB4PSIwIiB5PSIwIj48ZmVUdXJidWxlbmNlIGJhc2VGcmVxdWVuY3k9Ii43NSIgc3RpdGNoVGlsZXM9InN0aXRjaCIgdHlwZT0iZnJhY3RhbE5vaXNlIi8+PGZlQ29sb3JNYXRyaXggdHlwZT0ic2F0dXJhdGUiIHZhbHVlcz0iMCIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik0wIDBoMzAwdjMwMEgweiIgZmlsdGVyPSJ1cmwoI2EpIiBvcGFjaXR5PSIuMDUiLz48L3N2Zz4=')] opacity-30"></div>
|
|
|
|
<!-- Login Card -->
|
|
<Card.Root class="relative w-full max-w-md shadow-2xl backdrop-blur-sm">
|
|
<Card.Header class="space-y-3 text-center">
|
|
<!-- Logo/Icon -->
|
|
<div class="mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-primary/10">
|
|
<Lock class="h-8 w-8 text-primary" />
|
|
</div>
|
|
<Card.Title class="text-3xl font-bold tracking-tight">Welcome Back</Card.Title>
|
|
<Card.Description class="text-base">로그인하거나 새 계정을 만드세요</Card.Description>
|
|
</Card.Header>
|
|
|
|
<Card.Content class="space-y-6">
|
|
<form method="post" action="?/login" use:enhance class="space-y-5">
|
|
<div class="space-y-2">
|
|
<Label for="username" class="text-sm font-medium">사용자 이름</Label>
|
|
<div class="relative">
|
|
<div class="pointer-events-none absolute inset-y-0 left-0 z-10 flex items-center pl-3">
|
|
<User class="h-5 w-5 text-muted-foreground" />
|
|
</div>
|
|
<Input
|
|
id="username"
|
|
name="username"
|
|
type="text"
|
|
placeholder="username"
|
|
required
|
|
autocomplete="username"
|
|
class="relative z-20 pl-10"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="space-y-2">
|
|
<div class="flex items-center justify-between">
|
|
<Label for="password" class="text-sm font-medium">비밀번호</Label>
|
|
<button
|
|
type="button"
|
|
tabindex="-1"
|
|
class="text-xs text-primary focus:outline-none"
|
|
>
|
|
비밀번호 찾기
|
|
</button>
|
|
</div>
|
|
<div class="relative">
|
|
<div class="pointer-events-none absolute inset-y-0 left-0 z-10 flex items-center pl-3">
|
|
<Lock class="h-5 w-5 text-muted-foreground" />
|
|
</div>
|
|
<Input
|
|
id="password"
|
|
name="password"
|
|
type="password"
|
|
placeholder="••••••••"
|
|
required
|
|
autocomplete="current-password"
|
|
class="relative z-20 pl-10"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{#if form?.message}
|
|
<div
|
|
class="flex items-start gap-3 rounded-lg border border-destructive/50 bg-destructive/10 p-4 text-sm text-destructive"
|
|
>
|
|
<AlertCircle class="mt-0.5 h-5 w-5 flex-shrink-0" />
|
|
<span>{form.message}</span>
|
|
</div>
|
|
{/if}
|
|
|
|
<div class="flex flex-col gap-3 pt-2">
|
|
<Button
|
|
type="submit"
|
|
class="w-full"
|
|
size="lg"
|
|
>
|
|
<LogIn class="mr-2 h-5 w-5" />
|
|
로그인
|
|
</Button>
|
|
|
|
<div class="relative">
|
|
<div class="absolute inset-0 flex items-center">
|
|
<div class="w-full border-t border-muted"></div>
|
|
</div>
|
|
<div class="relative flex justify-center text-xs uppercase">
|
|
<span class="bg-card px-2 text-muted-foreground">또는</span>
|
|
</div>
|
|
</div>
|
|
|
|
<Button
|
|
type="submit"
|
|
formaction="?/register"
|
|
variant="outline"
|
|
class="w-full"
|
|
size="lg"
|
|
>
|
|
<UserPlus class="mr-2 h-5 w-5" />
|
|
새 계정 만들기
|
|
</Button>
|
|
</div>
|
|
</form>
|
|
</Card.Content>
|
|
|
|
<Card.Footer class="flex-col space-y-4">
|
|
<div class="text-center text-xs text-muted-foreground">
|
|
<p>계속 진행함으로써 서비스 약관 및 개인정보 보호정책에 동의하게 됩니다.</p>
|
|
</div>
|
|
</Card.Footer>
|
|
</Card.Root>
|
|
</div>
|