# رفع نمایش «ورود | ثبت‌نام» در هدر با وجود لاگین‌بودن کاربر ## پروژه `nobat724_front` — سایت عمومی. این کار **صرفاً frontend** است؛ backend تغییر نمی‌کند. ## زمینه هدر سایت عمومی بسته به وضعیت لاگین، یا دکمه‌ی «ورود | ثبت نام» را نشان می‌دهد یا آیکن پروفایل کاربر (`ProfileUser`). تصمیم بر اساس prop `logged` گرفته می‌شود که در `components/layout/StLayout.js` (Server Component) از روی کوکی `access_token` با `cookies()` خوانده و به هدر پاس داده می‌شود. مشکل: کاربر بعد از لاگین موفق (کوکی‌های `access_token`/`refresh_token`/`uuid`/`userInfo` با `js-cookie` ست می‌شوند)، **هنوز در هدر «ورود | ثبت نام» می‌بیند**. علت: `logged` فقط یک‌بار سمت سرور هنگام render محاسبه می‌شود و به ناوبری‌های client-side (soft navigation) و کوکی‌هایی که سمت کلاینت ست شده‌اند واکنش نشان نمی‌دهد؛ هدر تا یک hard-reload کامل وضعیت تازه را منعکس نمی‌کند و در بسیاری از مسیرها همان حالت اولیه‌ی «لاگین‌نشده» باقی می‌ماند. ## مشکل / هدف هدر باید وضعیت لاگین را **به‌صورت زنده سمت کلاینت** هم تشخیص دهد: اگر کوکی `access_token` وجود دارد → پروفایل، وگرنه → دکمه‌ی ورود. prop سرور (`logged`) به‌عنوان مقدار اولیه‌ی paint اول حفظ شود تا flash/hydration mismatch ندهد، ولی منبع نهایی تصمیم، کوکی سمت کلاینت باشد. ## فایل‌های مرتبط | فایل | نقش | |------|-----| | `components/layout/header/Content.js` | `"use client"`؛ بر اساس `logged` بین `ProfileUser` و دکمه‌ی ورود سوییچ می‌کند — محل اصلی رفع | | `components/layout/StLayout.js` | Server Component؛ `logged={token}` را از `cookies().get("access_token")` می‌دهد (مقدار اولیه) | | `components/layout/index.js` | layout کلاینتیِ پنل/داشبورد؛ `logged` را به‌صورت prop می‌گیرد | | `components/layout/header/index.js` | فقط prop را پاس می‌دهد | | `components/layout/header/profile/index.js` | `ProfileUser` — حالت لاگین‌شده | | `utils/index.js` | `removeToken()` — خروج | ## وضعیت فعلی (کد واقعی) ### `header/Content.js` — تصمیم فقط بر اساس prop سرور ```jsx "use client"; // ... function Content({ matchedCity, name, logged }) { // ... {logged ? ( ) : ( )} } ``` ### `StLayout.js` — مقدار اولیه از کوکی سرور ```jsx const cookieStore = await cookies(); const token = cookieStore.get("access_token"); // ...
``` > `token` یک شیء `{ name, value }` یا `undefined` است؛ پس `logged` truthy/undefined می‌شود. این فقط در render سرور محاسبه می‌شود. ### کوکی‌ها سمت کلاینت ست می‌شوند (`SendReq.js`) ```js Cookies.set("access_token", response.access_token, cookieOptions); // js-cookie, غیر httpOnly ``` ## وظایف ### ۱. تشخیص زنده‌ی لاگین در `header/Content.js` - یک state کلاینتی برای لاگین‌بودن اضافه کن که مقدار اولیه‌اش از prop `logged` (سرور) می‌آید تا paint اول درست باشد، سپس در `useEffect` با کوکی `access_token` همگام شود: ```jsx "use client"; import { useEffect, useState } from "react"; import Cookies from "js-cookie"; // ... function Content({ matchedCity, name, logged }) { const [isLogged, setIsLogged] = useState(Boolean(logged)); useEffect(() => { setIsLogged(Boolean(Cookies.get("access_token"))); }, []); // ... {isLogged ? : ...دکمه ورود...} } ``` - `Boolean(logged)` مهم است: `logged` ممکن است شیء `{name,value}` یا `undefined` باشد؛ تبدیل به boolean کن. - چون مقدار اولیه از سرور می‌آید، hydration mismatch رخ نمی‌دهد؛ بعد از mount با کوکی واقعی کلاینت تصحیح می‌شود. ### ۲. واکنش به تغییر مسیر (اختیاری ولی توصیه‌شده) - اگر لازم بود وضعیت بعد از login/logout بدون hard-reload به‌روز شود، می‌توانی `usePathname()` را به deps افزودن useEffect اضافه کنی تا با هر تغییر مسیر کوکی دوباره چک شود: ```jsx import { usePathname } from "next/navigation"; const pathname = usePathname(); useEffect(() => { setIsLogged(Boolean(Cookies.get("access_token"))); }, [pathname]); ``` > اگر فلوی فعلی login با `window.location.href` ریدایرکت می‌کند (hard reload)، paint اول سرور هم درست خواهد بود؛ این مرحله بیشتر برای ناوبری‌های soft و logout است. ### ۳. سازگاری logout - `ProfileUser`/`DetailProfile` هنگام logout `removeToken()` را صدا می‌زنند که کوکی‌ها را پاک می‌کند. مطمئن شو بعد از logout، هدر دوباره دکمه‌ی ورود را نشان می‌دهد (با همان مکانیزم کوکی‌خوانی + ناوبری/ریلود فعلی). اگر logout فقط state را عوض می‌کند و ریدایرکت ندارد، بررسی کن هدر به‌روز شود. ## نکات مهم - **هیچ تغییری در backend لازم نیست.** کوکی `access_token` غیر httpOnly است و سمت کلاینت با `js-cookie` قابل‌خواندن است. - **Hydration:** مقدار اولیه‌ی state حتماً از prop `logged` سرور باشد، نه مستقیماً از `Cookies.get` در زمان render؛ خواندن کوکی فقط داخل `useEffect` (بعد از mount) تا SSR و کلاینت در paint اول یکی باشند. - **multi-domain / RTL** را خراب نکن؛ منطق `matchedCity`/`name` دست‌نخورده بماند. - این هدر هم در `StLayout` (صفحات عمومی، logged از سرور) و هم در `components/layout/index.js` (پنل/داشبورد، logged از prop) استفاده می‌شود؛ هر دو مسیر باید بعد از تغییر کار کنند (در هر دو، fallback به prop + همگام‌سازی با کوکی درست عمل می‌کند). - **تست:** `npm run build`؛ سپس دستی: قبل از لاگین → دکمه‌ی «ورود | ثبت نام»؛ بعد از لاگین با `12345` و بازگشت به صفحه → آیکن پروفایل؛ بعد از logout → دوباره دکمه‌ی ورود. سپس commit با پیام توصیفی.