mirror of
https://github.com/temetro/temetro.git
synced 2026-08-30 04:09:05 +00:00
fix: clinic creation gating, analysis line charts, username + task assignee, delete confirm
- Hide "Create clinic" (sidebar footer) for non-admins; only owner/admin can spin up additional clinics. Onboarding for brand-new users is unaffected. - Analysis: drop the bar charts; show line charts (Sparkline) inside KPI cards that open a detail dialog with the full chart + per-point breakdown. - Add Team Member: validate the username client-side (no spaces; letters, numbers, dots, underscores) with a clear warning + field hint. - Tasks: New Task now has an Assignee selector (Myself / Other → department). Tasks are visible to the department they're assigned to (or the creator), and show who created them. Backend adds assignee_role + created_by_name with visibility filtering in listTasks; owners/admins see all. - Care team: removing a member now asks for confirmation first (dialog) and surfaces success/failure + refreshes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -322,20 +322,30 @@
|
||||
"details": "Details — what needs to be done",
|
||||
"detailsPlaceholder": "Describe what needs to happen, any context, links…",
|
||||
"assignee": "Assignee",
|
||||
"assigneePlaceholder": "e.g. Dr. Okafor",
|
||||
"assigneeSelf": "Myself",
|
||||
"assigneeOther": "Other",
|
||||
"department": "Department",
|
||||
"due": "Due",
|
||||
"duePlaceholder": "e.g. Today",
|
||||
"priorityLabel": "Priority",
|
||||
"cancel": "Cancel",
|
||||
"add": "Add task"
|
||||
},
|
||||
"list": {
|
||||
"forDept": "For {{dept}}",
|
||||
"personal": "Personal",
|
||||
"byCreator": "by {{name}}"
|
||||
},
|
||||
"detail": {
|
||||
"fallbackTitle": "Task",
|
||||
"priorityBadge": "{{priority}} priority",
|
||||
"status": "Status",
|
||||
"completed": "Completed",
|
||||
"open": "Open",
|
||||
"assignee": "Assignee",
|
||||
"assignedTo": "Assigned to",
|
||||
"createdBy": "Created by",
|
||||
"deptTeam": "{{dept}} team",
|
||||
"personal": "Personal task",
|
||||
"due": "Due",
|
||||
"patient": "Patient",
|
||||
"details": "Details",
|
||||
@@ -404,7 +414,10 @@
|
||||
"completed": "Completed"
|
||||
},
|
||||
"charts": {
|
||||
"patientGrowthTitle": "Patient growth",
|
||||
"title": "Trends",
|
||||
"subtitle": "Tap a card for the full breakdown.",
|
||||
"viewDetails": "Tap for details",
|
||||
"patientGrowthTitle": "New patients",
|
||||
"patientGrowthDescription": "New patients per month over the last 6 months",
|
||||
"weeklyAppointmentsTitle": "Appointments this week",
|
||||
"weeklyAppointmentsDescription": "Bookings per day for the current week",
|
||||
@@ -712,6 +725,18 @@
|
||||
"you": "(you)",
|
||||
"addMember": "Add team member",
|
||||
"removeMember": "Remove member",
|
||||
"remove": {
|
||||
"title": "Remove team member?",
|
||||
"description": "{{name}} will lose access to this clinic. This can't be undone.",
|
||||
"thisMember": "This member",
|
||||
"cancel": "Cancel",
|
||||
"confirm": "Remove",
|
||||
"removing": "Removing…",
|
||||
"removedTitle": "Member removed",
|
||||
"removedBody": "{{name}} no longer has access.",
|
||||
"failedTitle": "Couldn't remove member",
|
||||
"failedBody": "Please try again."
|
||||
},
|
||||
"add": {
|
||||
"title": "Add team member",
|
||||
"step1Description": "Who are you adding, and what can they do?",
|
||||
@@ -722,7 +747,9 @@
|
||||
"roleLabel": "Role",
|
||||
"usernameLabel": "Username",
|
||||
"usernamePlaceholder": "jokafor",
|
||||
"usernameHint": "Letters, numbers, dots and underscores — no spaces.",
|
||||
"usernameTooShort": "Username must be at least {{count}} characters.",
|
||||
"usernameInvalid": "Username can't contain spaces. Use letters, numbers, dots or underscores.",
|
||||
"passwordLabel": "Password",
|
||||
"passwordHint": "Must be at least {{count}} characters long.",
|
||||
"passwordTooShort": "Password must be at least {{count}} characters.",
|
||||
|
||||
@@ -17,6 +17,10 @@ export const PROVISIONABLE_ROLES: RoleKey[] = [
|
||||
"viewer",
|
||||
];
|
||||
|
||||
// Departments a task can be assigned to (member roles). Mirrors the backend's
|
||||
// TASK_DEPARTMENTS in lib/task-validation.ts.
|
||||
export const DEPARTMENTS = ["admin", "doctor", "reception"] as const;
|
||||
|
||||
// The current user's role in the active clinic (null while loading or if they
|
||||
// aren't a member). Re-fetches when the active organization changes.
|
||||
export function useActiveRole(): string | null {
|
||||
|
||||
@@ -8,11 +8,15 @@ export type Task = {
|
||||
id: string;
|
||||
title: string;
|
||||
assignee: string;
|
||||
// Department (member role) the task is assigned to; null = personal task.
|
||||
assigneeRole: string | null;
|
||||
due: string;
|
||||
priority: Priority;
|
||||
patient: string | null;
|
||||
notes: string | null;
|
||||
done: boolean;
|
||||
createdById: string | null;
|
||||
createdByName: string | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
@@ -21,6 +25,7 @@ export type Task = {
|
||||
export type TaskInput = {
|
||||
title: string;
|
||||
assignee?: string;
|
||||
assigneeRole?: string | null;
|
||||
due?: string;
|
||||
priority?: Priority;
|
||||
patient?: string | null;
|
||||
|
||||
Reference in New Issue
Block a user