Skip to the article
Aniq-UI

KinoraPages, roles and search

Pages, roles and search

What each page does, which role sees it, what each permission opens, and how the search finds pages and records.

For the Full Stack package

A member's pages

Every page exists in English under /en and in Arabic under /ar. The dashboard opens at /en/dashboard, after the sign-in at /en/auth/login. A member's pages need fitness.view, which only the Member role holds.

Sidebar itemPathWhat it does
Dashboard/en/dashboardToday at a glance: heart rate, energy and recovery, the activity rings, calories and macros, the sleep and heart-rate weeks, the next workouts and steps.
AI Assistant/en/dashboard/ai-assistantA chat that answers about the member's own training and logs for them.
Activity/en/dashboard/activitySteps, active time, calories and distance by day, week or month, an hourly heatmap, a breakdown by type, and a page per recorded activity with its route, splits, elevation and cadence.
Workouts/en/dashboard/workoutsThe week's plan, the coach's assigned work and weekly check-in, programs, each workout's page and the live session.
Exercise Library/en/dashboard/workouts/exercisesEvery movement, filtered by muscle, equipment and difficulty, with a page per movement.
Nutrition/en/dashboard/nutritionCalories, macros, hydration and the week's intake.
Meal Planner/en/dashboard/nutrition/meal-plannerA day's meals on a timeline, where the member logs food.
Sleep/en/dashboard/sleepStages, schedule, recovery and the week's trend.
Health/en/dashboard/healthA health score, the day's essentials, vitals and eight weeks of trends.
Progress/en/dashboard/progressPerformance, body metrics, habit streaks, records and achievements.
Progress Photos/en/dashboard/progress/photosBefore and after photos with a weight goal.
Community/en/dashboard/communityGroups, challenges, discussions, events and the leaderboard.
Settings/en/dashboard/settingsProfile, password, alerts, privacy, appearance, connected devices, billing and deleting the account.

Staff pages

Staff land on the coach overview at /en/dashboard: the roster at a glance, the clients who went quiet, the check-ins waiting for a reply, today's assigned work and the gym's accounts. The roster panels have data only for an account with coaching.clients (the Head Coach and the Personal Trainers), and the gym's accounts show only with members.view; for any other staff account, such as the seeded Coaches, the roster panels have nothing to show. Each other page appears only for a role that grants its permission.

Sidebar itemPathPermissionWhat it does
My Clients/en/dashboard/clientscoaching.clientsThe coach's own roster, and a page per client with their plan, check-ins and messages.
Gym/en/dashboard/users/allmembers.viewEvery member, each one's page, and the deleted members with a restore button.
Content/en/dashboard/contentfitness.manageThe catalogues members read: exercises, workouts, programs, dishes, groups, events, challenges, achievements and badges.
Coaches/en/dashboard/coachescoaches.viewStaff accounts and their roles.
Coach Roles/en/dashboard/coach-rolesroles.viewRoles and the permissions each grants.
Settings/en/dashboard/settingsEveryoneProfile, password, appearance and the app settings.

Two more entries sit under Demos: UI Component, every shared component rendered live with its code, and Onboarding, the guided first-run flow for a member. Remove them from navigationData.ts when you no longer want them.

The dashboard is never indexed by search engines: every page carries a noindex tag and public/robots.txt disallows every path.

The roles that ship

Members and staff share one accounts table and one sign-in; roles decide what each sees. An account holds every permission of every role it has. The seed creates seven roles:

RoleWhat it grants
Head CoachEvery permission except the training pair fitness.view and fitness.edit
CoachThe members, the coaches, the content, the roles list, the app settings and moving members between coaches
Gym ManagerThe members, the content, the coaches and roles lists, and moving members between coaches
EditorThe content, and the members and coaches lists
ViewerEvery .view permission except fitness.view: read-only gym screens
Personal TrainerTheir own roster (coaching.clients) and the content, without the members list
MemberThe training pair: their own fitness pages, and nothing behind them

Every role also holds ai_chat.use, ai_chat.view_models and settings.view: the assistant, and their own profile and preferences. Only the Member role trains, so a staff account never gets fitness pages of its own. A new account from the register page is a Member.

Permissions

ModulePermissions
Membersmembers.view, members.create, members.update, members.delete, members.restore, members.verify
Coachescoaches.view, coaches.create, coaches.edit, coaches.delete, coaches.assign_roles
Rolesroles.view, roles.create, roles.edit, roles.delete, roles.assign_permissions
Settingssettings.view, settings.edit
Fitnessfitness.view, fitness.edit (an account that trains), fitness.manage (the content catalogues)
Coachingcoaching.clients (your own roster), coaching.assign (moving members between coaches)
AI assistantai_chat.use, ai_chat.view_models

The sidebar, the pages and the API check the same names, so a role edited on the Coach Roles screen changes what its accounts see. An account that is signed in when its roles change gets the new permissions at once, over a live socket.

Ctrl+K, or Cmd+K on a Mac, opens the search from any page, as does the search box in the top bar. Arrows move through the results, Enter opens one and Escape closes it.

  • It finds the pages the account may open, and for a member the activities, workouts, exercises, dishes, sleep nights, achievements, groups, challenges and discussions in its built-in index. That index is read from the dashboard's own sample data, not from the database: with the API connected, those rows still come from the sample set, not from what each member logged.
  • With the API connected, it also asks the server for records the account may open: members, coaches, roles, and the content catalogues. Each kind needs the permission its own screen needs, so a member never sees another member in the results.
  • Rails down the side narrow the results to one kind. The last six searches are remembered in the browser.
  • On the sample data, the same search runs against the sample records.

How the server search works

GET /api/search?q=<term>&locale=<en|ar>&limit=<1-10> needs a signed-in token and no single permission. It runs one finder per kind the caller may open and leaves the others out.

KindMatchesPermission
member, coachFirst name, last name, both together, username, emailmembers.view, coaches.view
roleName, descriptionroles.view
exercise, workout, program, dish, group, event, challenge, achievement, badgeName and the kind's own fields, in both languages, and the slug or keyfitness.manage
  • A term under 2 characters answers no hits; a longer one is cut to 100. limit is per kind, 5 by default and at most 10.
  • A row whose text starts with the term ranks above one with a word that does, which ranks above one that only contains it. Ties keep the newest-updated first.
  • Each hit carries kind, title, detail, image and an href without the locale prefix. Deleted accounts are left out.

Settings

  • Profile and password: every account edits its own.
  • Alerts, privacy, devices and billing: a member's own. The four alert switches, sharing activity with the community, the connected devices and data sources, and the plan with its invoices. Billing is read only: nothing in the template takes a payment.
  • Appearance: light, dark or system theme, an accent colour and reduced motion, saved with the account so the look follows it between devices.
  • Export: a member downloads everything they have recorded as one JSON file.
  • Delete account: an account closes itself after confirming its password.
  • App settings: staff with settings.edit change the shared settings.

The seeded app settings are the site's name and tagline, two email addresses, maintenance mode, the default units, the first day of the week, the default goals (steps, water, sleep and calories) and two feature switches, for the community and the assistant. Only the AI assistant reads any of them: the units and the goals. The rest are stored and can be edited, but nothing reads them: turning on maintenance mode or switching a feature off changes nothing on screen until you wire it to your own code.

Stuck on a step?

Find a fix before you start over.

Troubleshooting

Cookie Preferences

We use cookies to enhance your browsing experience, analyze site traffic, and personalize content. By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising.