diff --git a/apps/api/src/routers/project.ts b/apps/api/src/routers/project.ts index b2489b5..8daf82f 100644 --- a/apps/api/src/routers/project.ts +++ b/apps/api/src/routers/project.ts @@ -74,7 +74,6 @@ export const projectRouter = router({ logoUrl: input.logoUrl ?? null, kind: input.kind, verantwortlicheUserId: input.verantwortlicheUserId ?? null, - arbeitsmodus: input.arbeitsmodus ?? null, outlineSteckbriefUrl: input.outlineSteckbriefUrl, planeProjectUrl: input.planeProjectUrl, risikolisteUrl: input.risikolisteUrl ?? null, diff --git a/apps/web/src/routes/bereich.tsx b/apps/web/src/routes/bereich.tsx index 878c3c0..bb0ef52 100644 --- a/apps/web/src/routes/bereich.tsx +++ b/apps/web/src/routes/bereich.tsx @@ -192,7 +192,6 @@ function ProjectCreateDialog({ } }, [areas, areaId, defaultSlug]); const [kind, setKind] = useState<'kundenprojekt' | 'internes_projekt'>('internes_projekt'); - const [arbeitsmodus, setArbeitsmodus] = useState<'cycle' | 'kanban'>('kanban'); const [steckbrief, setSteckbrief] = useState(''); const [plane, setPlane] = useState(''); @@ -215,7 +214,6 @@ function ProjectCreateDialog({ description: description.trim() || undefined, logoUrl: logoUrl ?? undefined, kind, - arbeitsmodus, outlineSteckbriefUrl: steckbrief, planeProjectUrl: plane, milestones: [], @@ -280,16 +278,6 @@ function ProjectCreateDialog({ - - - archiviert )} -

- {p.kind === 'kundenprojekt' ? 'Kundenprojekt' : 'Internes Projekt'} ·{' '} - {p.arbeitsmodus ?? '—'} · {p.deadline ? `Deadline ${p.deadline}` : 'kein Deadline'} -

+
+ {p.kind === 'kundenprojekt' ? 'Kundenprojekt' : 'Internes Projekt'} + · + +
@@ -243,6 +244,63 @@ function ModusControl({ projectId, modus }: { projectId: string; modus: ProjectM } // --- Ziel & Maxime + SMART-Ziel, Nicht-Ziele, Liefergegenstände, Zieldreieck - +function DeadlineControl({ projectId, deadline }: { projectId: string; deadline: string | null }) { + const utils = trpc.useUtils(); + const [editing, setEditing] = useState(false); + const [draft, setDraft] = useState(deadline ?? ''); + const update = trpc.project.update.useMutation({ + onSuccess: async () => { + toast(voice.toast.saved); + await utils.project.byId.invalidate({ id: projectId }); + setEditing(false); + }, + }); + + if (editing) { + const warnings = dateWarnings(draft || undefined); + return ( + + setDraft(e.target.value)} + className="rounded-[var(--radius-md)] border border-[var(--color-border)] bg-white px-2 py-1 text-sm text-[var(--color-ink)]" + /> + + + {warnings.length > 0 && ( + + {warnings[0]} + + )} + + ); + } + return ( + + ); +} + function HeaderLogo({ projectId, logoUrl, diff --git a/packages/shared/src/schemas/project.ts b/packages/shared/src/schemas/project.ts index f110783..b995441 100644 --- a/packages/shared/src/schemas/project.ts +++ b/packages/shared/src/schemas/project.ts @@ -18,7 +18,6 @@ export const createProjectInput = z.object({ logoUrl: logoUrlSchema.optional(), kind: z.enum(['kundenprojekt', 'internes_projekt']), verantwortlicheUserId: z.string().uuid().optional(), - arbeitsmodus: z.enum(['cycle', 'kanban']).optional(), outlineSteckbriefUrl: z.string().url(), planeProjectUrl: z.string().url(), risikolisteUrl: z.string().url().optional(), @@ -114,6 +113,16 @@ export const updateProjectInput = z.object({ liefergegenstaende: z.string().max(2000).nullable().optional(), zieldreieckFlex: zieldreieckFlexSchema.nullable().optional(), logoUrl: logoUrlSchema.nullable().optional(), + start: z + .string() + .regex(/^\d{4}-\d{2}-\d{2}$/) + .nullable() + .optional(), + deadline: z + .string() + .regex(/^\d{4}-\d{2}-\d{2}$/) + .nullable() + .optional(), outlineSteckbriefUrl: z.string().url().nullable().optional(), planeProjectUrl: z.string().url().nullable().optional(), risikolisteUrl: z.string().url().nullable().optional(),