4.7 KiB
name, description
| name | description |
|---|---|
| danak-admin | Documents danak-admin React admin panel conventions — page structure, routing, TanStack Query hooks, axios services, sidebar, and Persian i18n. Use when adding pages or features, wiring API calls, updating navigation, or working in this repository. |
Danak Admin
Persian (RTL) admin panel: React 19, Vite, TypeScript, React Router 7, TanStack Query, Formik/Yup, Tailwind, iconsax-react.
Stack
| Layer | Location / tool |
|---|---|
| Routes (paths) | src/config/Pages.ts |
| Route components | src/router/Main.tsx |
| Auth routes | src/router/Auth.tsx |
| HTTP client | src/config/axios.ts — import axios from "../../../config/axios" |
| Shared UI | src/components/ |
| Layout | src/shared/ (Header, SideBar, Footer) |
| i18n | src/langs/fa.json, namespace global, useTranslation('global') |
| Env | VITE_BASE_URL, VITE_TOKEN_NAME, VITE_REFRESH_TOKEN_NAME |
Feature folder layout
Each domain lives under src/pages/{feature}/:
{feature}/
├── List.tsx # index table view
├── Create.tsx # create form
├── Update.tsx # edit form (uses :id param)
├── hooks/use{Feature}Data.ts
├── service/{Feature}Service.ts
├── types/{Feature}Types.ts
└── components/ # feature-specific UI (Delete, filters, etc.)
Mirror an existing feature (e.g. customer/, ads/) before inventing new patterns.
Data layer
Service — plain async functions, one API call each:
import axios from "../../../config/axios";
import { CreateCustomerType } from "../types/CustomerTypes";
export const getCustomers = async (page: number) => {
const { data } = await axios.get(`/users/customers?page=${page}&paginate=1`);
return data;
};
export const createCustomer = async (params: CreateCustomerType) => {
const { data } = await axios.post(`/users/customers`, params);
return data;
};
Hooks — TanStack Query wrappers in hooks/use{Feature}Data.ts:
- Lists:
useQuery({ queryKey: ["customers", page], queryFn: () => api.getCustomers(page) }) - Detail: add
enabled: !!id - Mutations:
useMutation+queryClient.invalidateQueries({ queryKey: ["customers"] }) - Export hooks as
useGetX,useCreateX,useUpdateX,useDeleteX
Types — {Feature}ItemType, Create{Feature}Type in types/.
Page patterns
List — header + optional filters + PageLoading while pending + <table> with Td + Pagination. Link actions via Pages.{feature}.*.
Create / Update — Formik + Yup validation, toast(t('success'), 'success') on success, toast(error.response?.data?.error.message[0], 'error') on error (ErrorType from src/helpers/types.ts). Import toast from src/components/Toast. Navigate back to list with useNavigate() + Pages.*.
Delete — small component using ModalConfrim + mutation hook; call refetch() or rely on query invalidation.
Adding a feature
Follow the checklist in add-feature.md. Minimum steps:
- Add paths to
src/config/Pages.ts - Create page files under
src/pages/{feature}/ - Register
<Route>entries insrc/router/Main.tsx(static imports, no lazy loading) - Add sidebar entry in
src/shared/SideBar.tsxif user-facing - Add translation keys to
src/langs/fa.json
Dynamic routes use string concat: Pages.customer.update + ":id".
Sidebar & submenu
- Main sidebar shows group items (
menu,financial,other,content, …) viaSideBarItemwithnamematching the group key - Each group opens a side panel:
{Group}SubMenu.tsxinsrc/shared/components/(e.g.MenuSubMenu.tsx) - Map URL → group in
getSubMenuNameFromPath(src/config/SideBarSubMenu.ts) - Flat links inside a group:
SubMenuItem - Nested feature menus inside a group:
SubMenuAccordion(arrow open/close) wrappingSubMenuItemchildren subMenuNamecomes from the group key, not the feature path segment
Conventions
- Components:
const MyPage: FC = () => { ... }; export default MyPage - Styling: Tailwind utility classes;
clx()fromsrc/helpers/utilsfor conditional classes - Icons:
iconsax-react(Outline/Bold variants,#8C90A3inactive /blackactive) - Do not add lazy-loaded routes — project uses direct imports in
Main.tsx - Keep API paths relative to
VITE_BASE_URL; auth token is attached automatically by axios interceptor - Prefer reusing
Button,Input,Select,Textarea,Pagination,PageLoading,ModalConfrimfromsrc/components/
Do not
- Commit
.envor secrets - Introduce new state libraries (Zustand is only used in
sharedStorefor layout) - Add English-only UI strings — add keys to
fa.json - Change axios/auth/token refresh logic unless explicitly requested