feat: enhance UI components and implement password reset flow with improved styling and validation
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import { AppSidebar } from "@/components/Layouts/AppSidebar"
|
||||
import { Footer } from "@/components/Layouts/Footer"
|
||||
import { Header } from "@/components/Layouts/Header"
|
||||
import { Toaster } from "@/components/ui/toast"
|
||||
|
||||
@@ -9,20 +8,19 @@ export default function DashboardLayout({
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
return (
|
||||
<div className="flex min-h-screen bg-background">
|
||||
<div className="flex h-screen overflow-hidden bg-background">
|
||||
<AppSidebar />
|
||||
<main className="flex flex-1 flex-col">
|
||||
<Header />
|
||||
<div className="flex-1 overflow-auto">
|
||||
<div className="p-6 lg:p-8">
|
||||
<div className="rounded-xl bg-card border border-border shadow-sm">
|
||||
<div className="rounded-xl bg-card border border-gray-200 shadow-sm">
|
||||
<div className="p-6">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer className="border-t border-border mt-auto" />
|
||||
</main>
|
||||
<Toaster />
|
||||
</div>
|
||||
|
||||
@@ -43,7 +43,7 @@ export default function DashboardPage() {
|
||||
const [range, setRange] = React.useState<{ from: Date | undefined; to?: Date | undefined }>()
|
||||
return (
|
||||
<div className="flex flex-col gap-6">
|
||||
<div className="flex flex-col gap-5 rounded-xl bg-card p-6 shadow-sm border border-border">
|
||||
<div className="flex flex-col gap-5 rounded-xl bg-card p-6 shadow-sm border border-gray-200">
|
||||
<div>
|
||||
<p className="mb-2 text-sm font-semibold text-muted-foreground">Breadcrumb</p>
|
||||
<div className="flex flex-col gap-3">
|
||||
@@ -232,7 +232,7 @@ export default function DashboardPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-5 rounded-xl bg-card p-6 shadow-sm border border-border">
|
||||
<div className="flex flex-col gap-5 rounded-xl bg-card p-6 shadow-sm border border-gray-200">
|
||||
<div>
|
||||
<p className="mb-2 text-sm font-semibold text-muted-foreground">Alert Dialogs</p>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
@@ -294,7 +294,7 @@ export default function DashboardPage() {
|
||||
<RecentOrdersTable />
|
||||
|
||||
<div className="mt-6 grid grid-cols-1 gap-4 lg:grid-cols-3">
|
||||
<div className="rounded-xl bg-card p-6 shadow-sm border border-border">
|
||||
<div className="rounded-xl bg-card p-6 shadow-sm border border-gray-200">
|
||||
<h3 className="mb-4 text-sm font-semibold text-foreground">Sales (Line)</h3>
|
||||
<div className="h-56">
|
||||
<LineChart
|
||||
@@ -304,7 +304,7 @@ export default function DashboardPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl bg-card p-6 shadow-sm border border-border">
|
||||
<div className="rounded-xl bg-card p-6 shadow-sm border border-gray-200">
|
||||
<h3 className="mb-4 text-sm font-semibold text-foreground">Revenue (Bar)</h3>
|
||||
<div className="h-56">
|
||||
<BarChart
|
||||
@@ -314,7 +314,7 @@ export default function DashboardPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl bg-card p-6 shadow-sm border border-border">
|
||||
<div className="rounded-xl bg-card p-6 shadow-sm border border-gray-200">
|
||||
<h3 className="mb-4 text-sm font-semibold text-foreground">Product Mix (Pie)</h3>
|
||||
<div className="h-56">
|
||||
<PieChart labels={["A","B","C"]} data={[45, 30, 25]} />
|
||||
|
||||
@@ -25,10 +25,10 @@ export default function ForgotOtpPage() {
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-background to-background/95 p-4">
|
||||
<div className="w-full max-w-md rounded-xl bg-card p-8 shadow-lg border border-border">
|
||||
<div className="w-full max-w-2xl rounded-xl bg-card p-8 shadow-lg border border-gray-200">
|
||||
<div className="flex flex-col items-center mb-8">
|
||||
<div className="bg-primary/10 rounded-full p-4 mb-4">
|
||||
<Mail className="text-primary size-6" />
|
||||
<div className="bg-black/10 rounded-full p-4 mb-4">
|
||||
<Mail className="text-black size-6" />
|
||||
</div>
|
||||
<h1 className="text-2xl font-bold text-foreground text-center">Verify your email</h1>
|
||||
</div>
|
||||
@@ -46,7 +46,7 @@ export default function ForgotOtpPage() {
|
||||
e.preventDefault()
|
||||
handleResend()
|
||||
}}
|
||||
className="text-sm font-medium text-primary hover:text-primary/80 transition-colors"
|
||||
className="text-sm font-medium text-black hover:text-black/80 transition-colors"
|
||||
>
|
||||
Didn't receive the code? Resend
|
||||
</button>
|
||||
@@ -57,10 +57,10 @@ export default function ForgotOtpPage() {
|
||||
|
||||
<div className="flex gap-3">
|
||||
<Link href="/login" className="flex-1">
|
||||
<Button variant="outline" className="w-full">Back</Button>
|
||||
<Button variant="outline" className="w-full h-12 rounded-full border-gray-300 text-black hover:bg-black/5">Back</Button>
|
||||
</Link>
|
||||
<Link href="/login/forgot/reset" className="flex-1">
|
||||
<Button className="w-full">Verify</Button>
|
||||
<Button className="w-full h-12 rounded-full bg-black text-white hover:bg-black/90">Verify</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -19,8 +19,8 @@ export default function ForgotEmailPage() {
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-background to-background/95 px-4 py-8">
|
||||
<div className="w-full max-w-md rounded-xl bg-card p-8 shadow-lg border border-border">
|
||||
<div className="mb-8">
|
||||
<div className="w-full max-w-2xl rounded-xl bg-card p-8 pl-10 shadow-lg border border-gray-200">
|
||||
<div className="mb-8 text-center">
|
||||
<h1 className="text-2xl font-bold text-foreground">Reset your password</h1>
|
||||
<p className="mt-2 text-sm text-muted-foreground">Enter the email address associated with your account and we'll send you a one-time code to verify your identity.</p>
|
||||
</div>
|
||||
@@ -41,7 +41,7 @@ export default function ForgotEmailPage() {
|
||||
</div>
|
||||
|
||||
<Button
|
||||
className="w-full h-11 text-base font-medium"
|
||||
className="w-full h-12 text-base font-medium rounded-full bg-black text-white hover:bg-black/90"
|
||||
disabled={emailError !== ""}
|
||||
onClick={() => {
|
||||
if (email.length === 0) {
|
||||
@@ -53,16 +53,6 @@ export default function ForgotEmailPage() {
|
||||
>
|
||||
Send verification code
|
||||
</Button>
|
||||
|
||||
<div className="text-center">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => router.push('/login')}
|
||||
className="text-sm font-medium text-primary hover:text-primary/80 transition-colors"
|
||||
>
|
||||
Back to sign in
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -39,8 +39,8 @@ export default function ForgotResetPage() {
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-background to-background/95 p-4">
|
||||
<div className="w-full max-w-md rounded-xl bg-card p-8 shadow-lg border border-border">
|
||||
<div className="mb-8">
|
||||
<div className="w-full max-w-xl rounded-xl bg-card p-8 shadow-lg border border-gray-200">
|
||||
<div className="mb-8 text-center">
|
||||
<h1 className="text-2xl font-bold text-foreground">Create a new password</h1>
|
||||
<p className="mt-2 text-sm text-muted-foreground">Choose a strong password to secure your account.</p>
|
||||
</div>
|
||||
@@ -55,7 +55,7 @@ export default function ForgotResetPage() {
|
||||
value={password}
|
||||
onChange={(e) => setPassword((e.target as HTMLInputElement).value)}
|
||||
className="h-11 pr-11"
|
||||
placeholder="••••••••"
|
||||
placeholder="Enter your new password"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
@@ -76,7 +76,7 @@ export default function ForgotResetPage() {
|
||||
value={confirm}
|
||||
onChange={(e) => setConfirm((e.target as HTMLInputElement).value)}
|
||||
className="h-11 pr-11"
|
||||
placeholder="••••••••"
|
||||
placeholder="Confirm your new password"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
@@ -104,14 +104,14 @@ export default function ForgotResetPage() {
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => router.back()}
|
||||
className="flex-1 h-11"
|
||||
className="flex-1 h-12 rounded-full border-gray-300 text-black hover:bg-black/5"
|
||||
>
|
||||
Back
|
||||
</Button>
|
||||
<Button
|
||||
disabled={!allValid}
|
||||
onClick={() => setShowSuccess(true)}
|
||||
className="flex-1 h-11"
|
||||
className="flex-1 h-12 rounded-full bg-black text-white hover:bg-black/90"
|
||||
>
|
||||
Change password
|
||||
</Button>
|
||||
@@ -119,7 +119,7 @@ export default function ForgotResetPage() {
|
||||
</div>
|
||||
|
||||
<Dialog open={showSuccess} onOpenChange={setShowSuccess}>
|
||||
<DialogContent className="w-full max-w-sm">
|
||||
<DialogContent className="w-full max-w-lg sm:max-w-lg">
|
||||
<DialogHeader className="text-center">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<div className="flex items-center justify-center w-12 h-12 rounded-full bg-success/10 text-success">
|
||||
@@ -131,7 +131,7 @@ export default function ForgotResetPage() {
|
||||
</div>
|
||||
</div>
|
||||
</DialogHeader>
|
||||
<Button onClick={() => router.push('/login')} className="w-full mt-6">
|
||||
<Button onClick={() => router.push('/login')} className="w-4/5 mx-auto h-12 mt-6 rounded-full bg-black text-white hover:bg-black/90">
|
||||
Return to sign in
|
||||
</Button>
|
||||
</DialogContent>
|
||||
|
||||
@@ -106,7 +106,7 @@ export default function LoginPage() {
|
||||
type={showPassword ? "text" : "password"}
|
||||
autoComplete="current-password"
|
||||
className="h-11 rounded-lg px-4 pr-11 text-base"
|
||||
placeholder="••••••••"
|
||||
placeholder="Enter your password"
|
||||
aria-invalid={!!form.formState.errors.password}
|
||||
{...form.register("password")}
|
||||
/>
|
||||
@@ -161,7 +161,7 @@ export default function LoginPage() {
|
||||
|
||||
<Button
|
||||
type="button"
|
||||
className="w-full h-11 text-base font-medium inline-flex items-center justify-center gap-3 bg-black text-white border-0 hover:opacity-90"
|
||||
className="w-full h-11 text-base font-medium inline-flex items-center justify-center gap-3 rounded-full bg-transparent text-foreground border border-gray-300 hover:bg-black/5"
|
||||
onClick={() => {
|
||||
alert('Google OAuth flow placeholder')
|
||||
}}
|
||||
@@ -173,7 +173,7 @@ export default function LoginPage() {
|
||||
|
||||
<div className="mt-12 text-center">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Don't have an account? <Link href="#" className="font-semibold text-primary hover:text-primary/80 transition-colors">Create an account</Link>
|
||||
Don't have an account? <Link href="#" className="font-semibold text-black hover:text-black/80 transition-colors">Create an account</Link>
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
Reference in New Issue
Block a user