Initial commit: personal task planner with categories, projects, and tiered assignment
Personal-first lists/tasks/reminders/recurrence, plus an admin-editable status pipeline, shared categories, project containers, and a three-tier permission model for cross-user work: assign (hand off your own tasks), reallocate (dispatcher — move anyone's tasks), admin (reserved, full manage-all).
This commit is contained in:
commit
d8dc4e2b81
54 changed files with 10908 additions and 0 deletions
97
frontend/src/types.ts
Normal file
97
frontend/src/types.ts
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
export type Priority = 'low' | 'medium' | 'high'
|
||||
export type Status = 'todo' | 'doing' | 'done'
|
||||
export type RecurRule = 'daily' | 'weekdays' | 'weekly' | 'monthly'
|
||||
|
||||
export const PRIORITIES: Priority[] = ['low', 'medium', 'high']
|
||||
export const PRIORITY_LABELS: Record<Priority, string> = { low: 'Low', medium: 'Medium', high: 'High' }
|
||||
|
||||
export const STATUSES: Status[] = ['todo', 'doing', 'done']
|
||||
export const STATUS_LABELS: Record<Status, string> = { todo: 'To do', doing: 'Doing', done: 'Done' }
|
||||
|
||||
export const RECUR_RULES: RecurRule[] = ['daily', 'weekdays', 'weekly', 'monthly']
|
||||
export const RECUR_LABELS: Record<RecurRule, string> = {
|
||||
daily: 'Every day',
|
||||
weekdays: 'Every weekday',
|
||||
weekly: 'Every week',
|
||||
monthly: 'Every month',
|
||||
}
|
||||
|
||||
// Preset list colours (user data, not design-system chrome).
|
||||
export const LIST_COLOURS = ['#c9a84c', '#0d9488', '#2563eb', '#7c3aed', '#dc2626', '#d97706', '#16a34a', '#64748b']
|
||||
|
||||
export interface List {
|
||||
id: number
|
||||
owner_id: string
|
||||
name: string
|
||||
colour: string
|
||||
icon: string
|
||||
sort_order: number
|
||||
is_archived: boolean
|
||||
open_count: number
|
||||
total_count: number
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export interface Task {
|
||||
id: number
|
||||
list_id: number
|
||||
owner_id: string
|
||||
created_by: string
|
||||
assigned_to: string | null
|
||||
title: string
|
||||
notes: string | null
|
||||
status: Status
|
||||
priority: Priority
|
||||
due_at: string | null
|
||||
remind_at: string | null
|
||||
reminded_at: string | null
|
||||
recur_rule: RecurRule | null
|
||||
completed_at: string | null
|
||||
sort_order: number
|
||||
created_at: string
|
||||
updated_at: string
|
||||
// joined / derived
|
||||
list_name?: string
|
||||
list_colour?: string
|
||||
item_count?: number
|
||||
item_done?: number
|
||||
}
|
||||
|
||||
export interface TaskItem {
|
||||
id: number
|
||||
task_id: number
|
||||
label: string
|
||||
is_done: boolean
|
||||
sort_order: number
|
||||
}
|
||||
|
||||
export interface TaskComment {
|
||||
id: number
|
||||
task_id: number
|
||||
author_email: string | null
|
||||
author_name: string | null
|
||||
body: string
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export interface TaskDetail extends Task {
|
||||
items: TaskItem[]
|
||||
comments: TaskComment[]
|
||||
}
|
||||
|
||||
export interface AppConfig {
|
||||
remind_by_push: boolean
|
||||
remind_by_email: boolean
|
||||
}
|
||||
|
||||
export interface User {
|
||||
user_id: number
|
||||
name: string
|
||||
email: string
|
||||
is_admin: boolean
|
||||
caps: string[] // bare slugs — verify?app=tasks strips the prefix
|
||||
}
|
||||
|
||||
export function can(user: User, cap: string): boolean {
|
||||
return user.is_admin || user.caps.includes(cap)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue