قالب صفحهٔ ورود (AuthPage)
صفحهٔ بیرون از قاب برای ورود، کد یکبارمصرف و بازیابی گذرواژه — وسط صفحه، نشان محصول، یک اقدام اصلی
معرفی
AuthPage قالب صفحههایی است که کاربر پیش از ورود میبیند: ورود، کد یکبارمصرف، بازیابی گذرواژه. این صفحهها
بیرون از ProductFrame هستند (منو و سرِ قاب برای کاربری که وارد نشده معنایی ندارد) و قالب همهچیز را خودش دارد:
- وسط صفحه، نشان و نام محصول بالای یک کارت باریک (
--layout-auth-width، 400 پیکسل)؛ - عنوان کار صفحه (تنها
h1)، یک جمله زیرش، فیلدها (FormRow، برچسب بالای فیلد)؛ - یک اقدام اصلی: دکمهٔ ثبت تمامعرض؛ پیوندهای متنی زیرش («فراموشی گذرواژه»)؛
- خطای تلاش ناموفق در یک خلاصه بالای فیلدها با عنوان «درخواست انجام نشد» (نه «ذخیره انجام نشد» فرمها)، اعلامشده و فوکوسشده؛
- جای کنترلهای زبان و پوسته در گوشهٔ بالای صفحه، و یک خط پایین کارت (مجوز، نسخه)؛
- ناحیهٔ
mainصفحه را خودش میسازد.
چه زمانی استفاده کنیم: ورود، مرحلهٔ کد یکبارمصرف، بازیابی و تنظیم گذرواژهٔ تازه.
چه زمانی استفاده نکنیم:
- هر صفحهای پس از ورود: قالب همان صفحه داخل قاب (تغییر گذرواژه در تنظیمات یک
FormPageاست). - ثبتنام چندمرحلهای:
WizardPage— داخل قاب اگر کاربر وارد شده، وگرنه همان مسیر بیرون از قاب.
استفاده
در Next.js، قاب لایهٔ گروه مسیرهای ورودشده است و صفحهٔ ورود در گروه دیگری بیرون از آن:
app/layout.tsx ← html، body و Toaster؛ بی قاب
app/(app)/layout.tsx ← <Frame>{children}</Frame>
app/(app)/mentions/page.tsx
app/(auth)/login/page.tsx ← metadata و <Login />
app/(auth)/login/login.tsx ← 'use client': <LoginScreen onSignedIn={() => router.push('/')} />
app/not-found.tsx ← <Frame><UtilityPage kind="404" …/></Frame> (بیرون از هر گروه، پس قاب را خودش دارد)'use client'
import * as React from 'react'
import Link from 'next/link'
import { useForm } from 'react-hook-form'
import { Button, Input } from '@partodata/ui'
import { Form, FormField } from '@partodata/ui/form'
import { AuthPage, FormRow } from '@partodata/ui/templates'
type SignIn = { email: string; password: string }
async function signIn(values: SignIn): Promise<void> {
const response = await fetch('/api/session', { method: 'POST', body: JSON.stringify(values) })
if (!response.ok) throw new Error(`session: ${response.status}`)
}
export function LoginScreen({ onSignedIn }: { onSignedIn: () => void }) {
const form = useForm<SignIn>({ defaultValues: { email: '', password: '' } })
const submit = form.handleSubmit(async (values) => {
try {
await signIn(values)
onSignedIn()
} catch {
form.setError('root', { message: 'ایمیل یا گذرواژه درست نیست' })
}
})
return (
<Form {...form}>
<AuthPage
product={{ name: 'پایش منشن' }}
title="ورود به حساب"
description="با ایمیل سازمانی خود وارد شوید."
onSubmit={submit}
submitLabel="ورود"
submitting={form.formState.isSubmitting}
error={form.formState.errors.root?.message}
links={
<Button variant="link" asChild>
<Link href="/reset">فراموشی گذرواژه</Link>
</Button>
}
>
<FormField
control={form.control}
name="email"
rules={{ required: 'ایمیل را وارد کنید' }}
render={({ field, fieldState }) => (
<FormRow label="ایمیل" required error={fieldState.error?.message}>
<Input kind="email" {...field} />
</FormRow>
)}
/>
<FormField
control={form.control}
name="password"
rules={{ required: 'گذرواژه را وارد کنید' }}
render={({ field, fieldState }) => (
<FormRow label="گذرواژه" required error={fieldState.error?.message}>
<Input kind="password" {...field} />
</FormRow>
)}
/>
</AuthPage>
</Form>
)
}حالتها و انواع
| صفحه | title | فیلدها | submitLabel | links / back |
|---|---|---|---|---|
| ورود | «ورود به حساب» | ایمیل، گذرواژه | «ورود» | «فراموشی گذرواژه» |
| کد یکبارمصرف | «کد تأیید را وارد کنید» | InputOTP | «تأیید کد» | «ارسال دوباره کد»؛ back به «ورود» |
| بازیابی گذرواژه | «بازیابی گذرواژه» | ایمیل | «ارسال پیوند بازیابی» | back به «ورود» |
خطای تلاش ناموفق هرگز نمیگوید کدام فیلد اشتباه بود («ایمیل یا گذرواژه درست نیست»).
راهنمای استفاده
بکنید
- صفحههای پیش از ورود را در گروه مسیری بیرون از قاب بگذارید و هر کدام را یک
AuthPageکنید. productهمان محصول قاب است؛logoفقط نشان خود محصول.- پیوندهای کمکی را
Button variant="link"باLinkبنویسید، درlinks.
نکنید
AuthPageرا داخلProductFrameنگذارید (در محیط توسعه هشدار میدهد).- دکمهٔ دوم (ثبتنام، ورود با روش دیگر) را اقدام اصلی نکنید؛ پیوند متنی است.
- کارت،
h1یا دکمهٔ ثبت خودتان نسازید.
Props
AuthPage
AuthPageProduct
دسترسیپذیری
- صفحه ناحیهٔ
mainخودش را دارد و عنوان تنهاh1است؛ فرم با نام عنوان. - خطای تلاش ناموفق هشدار (
role="alert") است و فوکوس میگیرد، هر بار که دوباره شکست بخورد. - فیلدها با
FormRowبرچسب، توضیح و پیام خطای خودشان را دارند.
کامپوننتهای مرتبط
FormRow— فیلدهای صفحه.ProductFrame— قاب صفحههای پس از ورود.- انتخاب قالب صفحه