199 lines
5.3 KiB
Vue
199 lines
5.3 KiB
Vue
<script setup lang="ts">
|
|
import { Head, useForm } from '@inertiajs/vue3';
|
|
import { ChevronLeft } from 'lucide-vue-next';
|
|
import InputError from '@/components/InputError.vue';
|
|
import TextLink from '@/components/TextLink.vue';
|
|
import Button from '@/components/ui/button.vue';
|
|
import Input from '@/components/ui/input.vue';
|
|
import Label from '@/components/ui/label.vue';
|
|
import Spinner from '@/components/ui/spinner.vue';
|
|
import UserLayout from '@/layouts/user/userlayout.vue';
|
|
|
|
defineProps<{
|
|
status?: string;
|
|
}>();
|
|
|
|
const form = useForm({
|
|
email: '',
|
|
});
|
|
|
|
const submit = () => {
|
|
form.post('/forgot-password');
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<UserLayout>
|
|
<Head title="Forgot Password" />
|
|
|
|
<div class="login-container">
|
|
<!-- Animated Background -->
|
|
<div class="glow-orb orb-1"></div>
|
|
<div class="glow-orb orb-2"></div>
|
|
|
|
<div class="login-card">
|
|
<div class="card-header">
|
|
<h1 class="title">RESET <span class="highlight">PASSWORD</span></h1>
|
|
<p class="subtitle">Enter your email to recover access</p>
|
|
</div>
|
|
|
|
<div v-if="status" class="mb-4 text-center text-sm font-medium text-green-500 bg-green-500/10 p-2 rounded border border-green-500/20">
|
|
{{ status }}
|
|
</div>
|
|
|
|
<form @submit.prevent="submit" class="form-content">
|
|
|
|
<div class="input-group">
|
|
<Label for="email">Email Address</Label>
|
|
<Input
|
|
id="email"
|
|
type="email"
|
|
v-model="form.email"
|
|
required
|
|
autofocus
|
|
placeholder="you@example.com"
|
|
/>
|
|
<InputError :message="form.errors.email" />
|
|
</div>
|
|
|
|
<div class="mt-6">
|
|
<Button
|
|
type="submit"
|
|
class="w-full h-12 text-base font-bold tracking-widest uppercase neon-button relative overflow-hidden"
|
|
:disabled="form.processing"
|
|
>
|
|
<div v-if="form.processing" class="absolute inset-0 bg-black/20 flex items-center justify-center">
|
|
<Spinner class="w-5 h-5" />
|
|
</div>
|
|
<span :class="{ 'opacity-0': form.processing }">Send Reset Link</span>
|
|
</Button>
|
|
</div>
|
|
|
|
<div class="text-center mt-6">
|
|
<TextLink href="/login" class="text-[#888] hover:text-white transition-colors flex items-center justify-center gap-2">
|
|
<ChevronLeft class="w-4 h-4" /> Back to Login
|
|
</TextLink>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</UserLayout>
|
|
</template>
|
|
|
|
<style scoped>
|
|
/* Container & Layout */
|
|
.login-container {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-height: calc(100vh - 100px);
|
|
padding: 20px;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.login-card {
|
|
width: 100%;
|
|
max-width: 450px;
|
|
background: rgba(10, 10, 10, 0.8);
|
|
backdrop-filter: blur(20px);
|
|
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
border-radius: 24px;
|
|
padding: 40px;
|
|
position: relative;
|
|
z-index: 10;
|
|
box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
|
|
animation: slideUp 0.8s cubic-bezier(0.16, 1, 0.3, 1);
|
|
}
|
|
|
|
/* Header */
|
|
.card-header {
|
|
text-align: center;
|
|
margin-bottom: 30px;
|
|
}
|
|
.title {
|
|
font-size: 1.8rem;
|
|
font-weight: 900;
|
|
color: white;
|
|
letter-spacing: 2px;
|
|
margin: 0;
|
|
}
|
|
.highlight {
|
|
color: #ff007a;
|
|
text-shadow: 0 0 20px rgba(255, 0, 122, 0.5);
|
|
}
|
|
.subtitle {
|
|
color: #888;
|
|
font-size: 0.9rem;
|
|
margin-top: 5px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 1px;
|
|
}
|
|
|
|
/* Form Content */
|
|
.form-content {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 20px;
|
|
}
|
|
.input-group {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
/* Neon Button */
|
|
.neon-button {
|
|
background: linear-gradient(90deg, #ff007a, #be005b);
|
|
border: none;
|
|
position: relative;
|
|
overflow: hidden;
|
|
transition: all 0.3s ease;
|
|
}
|
|
.neon-button:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 0 30px rgba(255, 0, 122, 0.6);
|
|
filter: brightness(1.1);
|
|
}
|
|
.neon-button:disabled {
|
|
opacity: 0.5;
|
|
cursor: not-allowed;
|
|
filter: grayscale(1);
|
|
}
|
|
|
|
/* Background Orbs */
|
|
.glow-orb {
|
|
position: absolute;
|
|
border-radius: 50%;
|
|
filter: blur(80px);
|
|
opacity: 0.4;
|
|
z-index: 0;
|
|
animation: float 10s infinite ease-in-out;
|
|
}
|
|
.orb-1 {
|
|
width: 300px;
|
|
height: 300px;
|
|
background: #ff007a;
|
|
top: -50px;
|
|
left: -100px;
|
|
}
|
|
.orb-2 {
|
|
width: 400px;
|
|
height: 400px;
|
|
background: #00f2ff;
|
|
bottom: -100px;
|
|
right: -100px;
|
|
animation-delay: -5s;
|
|
}
|
|
|
|
/* Animations */
|
|
@keyframes slideUp {
|
|
from { opacity: 0; transform: translateY(40px) scale(0.95); }
|
|
to { opacity: 1; transform: translateY(0) scale(1); }
|
|
}
|
|
@keyframes float {
|
|
0%, 100% { transform: translate(0, 0); }
|
|
50% { transform: translate(20px, 30px); }
|
|
}
|
|
</style>
|