fix(frontend): restore member self-assignment for shifts and tasks
All checks were successful
CI Pipeline / Backend Build & Test (push) Successful in 1m12s
CI Pipeline / Frontend Lint, Test & Build (push) Successful in 35s
CI Pipeline / Infrastructure Validation (push) Successful in 4s
CI Pipeline / Backend Build & Test (pull_request) Successful in 52s
CI Pipeline / Frontend Lint, Test & Build (pull_request) Successful in 33s
CI Pipeline / Infrastructure Validation (pull_request) Successful in 4s

Root Cause:
- Shift: Next.js 16.1.6 incompatible rewrite pattern caused runtime SyntaxError
- Task: Missing self-assignment UI for member role

Fix:
- Updated next.config.ts rewrite pattern from regex to wildcard syntax
- Added "Assign to Me" button to task detail page with useSession integration
- Added test coverage for self-assignment behavior with session mocks

Testing:
- Lint:  PASS (ESLint v9)
- Tests:  47/47 PASS (Vitest v4.0.18)
- Build:  PASS (Next.js 16.1.6, 12 routes)

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
WorkClub Automation
2026-03-08 19:07:19 +01:00
parent 785502f113
commit add4c4c627
5 changed files with 159 additions and 2 deletions

View File

@@ -6,6 +6,7 @@ import { useTask, useUpdateTask } from '@/hooks/useTasks';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { useSession } from 'next-auth/react';
const VALID_TRANSITIONS: Record<string, string[]> = {
Open: ['Assigned'],
@@ -26,6 +27,7 @@ export default function TaskDetailPage({ params }: { params: Promise<{ id: strin
const resolvedParams = use(params);
const { data: task, isLoading, error } = useTask(resolvedParams.id);
const { mutate: updateTask, isPending } = useUpdateTask();
const { data: session } = useSession();
if (isLoading) return <div className="p-8">Loading task...</div>;
if (error || !task) return <div className="p-8 text-red-500">Failed to load task.</div>;
@@ -36,6 +38,12 @@ export default function TaskDetailPage({ params }: { params: Promise<{ id: strin
updateTask({ id: task.id, data: { status: newStatus } });
};
const handleAssignToMe = () => {
if (session?.user?.id) {
updateTask({ id: task.id, data: { assigneeId: session.user.id } });
}
};
const getTransitionLabel = (status: string, newStatus: string) => {
if (status === 'Review' && newStatus === 'InProgress') return 'Back to InProgress';
if (newStatus === 'Done') return 'Mark as Done';
@@ -93,6 +101,15 @@ export default function TaskDetailPage({ params }: { params: Promise<{ id: strin
<div className="pt-6 border-t">
<h3 className="text-lg font-medium mb-4">Actions</h3>
<div className="flex flex-wrap gap-2">
{!task.assigneeId && session?.user && (
<Button
onClick={handleAssignToMe}
disabled={isPending}
variant="outline"
>
{isPending ? 'Assigning...' : 'Assign to Me'}
</Button>
)}
{validTransitions.map((nextStatus) => (
<Button
key={nextStatus}