# Gameno Dashboard - Persian Teaching Institution Admin Dashboard A complete, production-ready admin dashboard built with Vue 3 (Composition API), PrimeVue 4, PrimeFlex, Pinia, Vue Router 4, vue-i18n, and Axios. Designed specifically for managing an educational institution in Persian (RTL layout) with role-based access control (RBAC). --- ## πŸš€ Setup and Installation ### Prerequisites - Node.js v18+ and npm v9+ ### Commands ```bash # 1. Install dependencies npm install # 2. Run local development server npm run dev # 3. Build production bundle npm run build # 4. Preview production build npm run preview ``` --- ## πŸ—ΊοΈ Route Permission Mapping All routes enforce client-side permission checks via global navigation guards (`/src/router/guards.js`) and UI element visibility gates (``). | Route Path | View Component | Required Permission | Description | | :--- | :--- | :--- | :--- | | `/login` | `LoginView.vue` | Public | Admin login page | | `/` | `DashboardHomeView.vue` | Authenticated | Dashboard home statistics & shortcuts | | `/users` | `UserListView.vue` | `users:read` | List students & staff | | `/users/create` | `UserFormView.vue` | `users:create` | Create new user | | `/users/edit/:id` | `UserFormView.vue` | `users:update` | Edit user profile | | `/users/:id` | `UserDetailView.vue` | `users:read` | Profile summary, courses, payments, certificates | | `/professors` | `ProfessorListView.vue` | `professors:read` | List instructors | | `/professors/create` | `ProfessorFormView.vue` | `professors:create` | Add instructor | | `/professors/edit/:id` | `ProfessorFormView.vue` | `professors:update` | Edit instructor | | `/courses` | `CourseListView.vue` | `courses:read` | List courses | | `/courses/create` | `CourseFormView.vue` | `courses:create` | Create course & auto/manual session generator | | `/courses/edit/:id` | `CourseFormView.vue` | `courses:update` | Edit course & sessions | | `/courses/:id` | `CourseDetailView.vue` | `courses:read` | Course details & sessions overview | | `/sessions` | `SessionListView.vue` | `sessions:read` | List scheduled sessions | | `/sessions/create` | `SessionFormView.vue` | `sessions:create` | Schedule single session | | `/sessions/edit/:id` | `SessionFormView.vue` | `sessions:update` | Edit session details | | `/attendances/session/:id` | `AttendanceEntryView.vue` | `sessions:attendance` | Bulk session attendance entry | | `/payments` | `PaymentListView.vue` | `payments:read` | Payment ledgers & invoices | | `/payments/:id` | `PaymentDetailView.vue` | `payments:read` | Payment detail & record transactions | | `/roles` | `RoleListView.vue` | `roles:read` | List custom roles | | `/roles/create` | `RoleFormView.vue` | `roles:create` | Create role & permission matrix | | `/roles/edit/:id` | `RoleFormView.vue` | `roles:update` | Edit role permissions | | `/notifications` | `NotificationListView.vue` | `notifications:read` | Delivery log & manual retry | | `/forbidden` | `ForbiddenView.vue` | Authenticated | 403 Forbidden page | | `/*` | `NotFoundView.vue` | Public | 404 Not Found page | --- ## βš™οΈ Automatic Session Date Generation Algorithm In `CourseFormView.vue` (Automatic Tab): 1. **Inputs**: Admin specifies requested total sessions count (e.g. `12`), start date in Jalali Shamsi format (e.g. `1403/01/01`), start/end time, and selected weekdays (e.g. Saturday = 6, Tuesday = 2). 2. **Rolling Calendar Loop**: - Converts the start date into a `moment` instance in Jalali locale. - Iteratively increments day by day. - Checks if `currentMoment.day()` matches any of the chosen weekdays. - When matched, increments session counter and pushes a preview row object (`sessionNumber`, `date` formatted in Jalali `YYYY/MM/DD`, `startTime`, `endTime`, `topic`). 3. **Interactive Preview**: Renders an inline editable data table so the admin can review or manually adjust individual row dates or topics before final submission. 4. **Bulk Dispatch**: Sends the generated session array to `POST /sessions/admin/create` in a single API request. --- ## πŸ“ Key Architecture Assumptions 1. **Authentication & Token Storage**: - JWT `accessToken` and `refreshToken` are stored in `localStorage` and synchronized with HTTP cookies via `js-cookie`. - Axios request interceptor attaches `Authorization: Bearer `. - On `401 Unauthorized` responses, Axios automatically triggers silent token renewal calling `POST /auth/refresh`. 2. **Permission Store Rehydration**: - Permissions array is loaded once on login from `response.user.role.permissions`. - On hard page refresh, if a valid token exists but Pinia store is unpopulated, `guards.js` triggers `GET /users/user/get-self` once to rehydrate permissions. 3. **Certificate Upload Flow**: - Uses two-stage S3/MinIO upload strategy. - `ImageManager.vue` uploads binary file to `POST /files/admin/upload-temp` returning a temporary filename (`tempFileName`). - Committing a certificate form dispatches `tempFileName` to `/certificates/user/upload`, moving the file to persistent storage on the backend.