60 lines
1.4 KiB
TypeScript
60 lines
1.4 KiB
TypeScript
import { ulid } from 'https://deno.land/x/ulid@v0.3.0/mod.ts'
|
|
import { z } from 'https://deno.land/x/zod@v3.21.4/mod.ts'
|
|
|
|
export const Identifiable = z.object({
|
|
id: z.string().ulid().describe('primary').default(ulid),
|
|
})
|
|
|
|
const KVO = Identifiable
|
|
|
|
export const Created = z.object({
|
|
createdAt: z.date().default(() => new Date()),
|
|
})
|
|
|
|
export const User = KVO.merge(z.object({
|
|
name: z.string(),
|
|
avatarUrl: z.string().default('https://placekitten.com/512/512'),
|
|
color: z.string().default('#00aaff'),
|
|
}))
|
|
export type User = z.infer<typeof User>
|
|
|
|
export const Todo = KVO.merge(z.object({
|
|
description: z.string(),
|
|
emoji: z.string().nullable(),
|
|
doneAt: z.date().nullable(),
|
|
assigneeUserId: z.string().ulid().nullable(),
|
|
}))
|
|
export type Todo = z.infer<typeof Todo>
|
|
|
|
export const DailyPhase = z.enum([
|
|
'Morning',
|
|
'Midday',
|
|
'Evening',
|
|
'Bedtime',
|
|
'Night',
|
|
])
|
|
export type DailyPhase = z.infer<typeof DailyPhase>
|
|
|
|
export function toPhase(dt?: Date | null): DailyPhase {
|
|
const d = dt || new Date()
|
|
const h = d.getHours()
|
|
|
|
if (h >= 6 && h < 12) {
|
|
return 'Morning'
|
|
} else if (h >= 12 && h < 17) {
|
|
return 'Midday'
|
|
} else if (h >= 17 && h < 19) {
|
|
return 'Evening'
|
|
} else if (h >= 19 && h < 23) {
|
|
return 'Bedtime'
|
|
}
|
|
|
|
// if (h >= 21 || h < 6) {
|
|
return 'Night'
|
|
// } else
|
|
}
|
|
|
|
export const Task = Todo.omit({ assigneeUserId: true }).merge(z.object({
|
|
phase: DailyPhase,
|
|
}))
|
|
export type Task = z.infer<typeof Task>
|