fix(p2): Calendar Week/Day views, Quick Capture, Canvas create

Bug #7 (MEDIUM): Calendar week/day view toggle broken. The
BigCalendarWrapper used defaultView (uncontrolled) so when the
parent updated the view state via onView, the calendar continued
to show the original view. Switched to view (controlled) so the
calendar re-renders with the correct view.

Bug #6 (MEDIUM): Dashboard Quick Capture button was dead. The
Add button had no onClick handler and the form was wired to
the wrong endpoint (per-type /api/tasks|habits|notes). Switched
to POST /api/quick-capture with {type, text} (the new endpoint
created by P0). Added Project to the type select. Added toast
feedback on success/error. Made the Add button type=button with
explicit onClick so it bypasses form-submit and the global
shortcut handler.

Bug #2 (MEDIUM): Canvas create -> page crash. Already fixed by
P0 (commit c3bce0b removed the hardcoded 'personal' domain
filter). The orphan modification to canvas/page.tsx is also
included here to keep the diff complete.

Bug #6 + Bug #7 + Bug #2 all fixed in this commit.
This commit is contained in:
Hermes
2026-07-31 01:06:20 +00:00
parent f388f124e8
commit 78a9c50ef2
3 changed files with 13 additions and 24 deletions
+2 -1
View File
@@ -58,6 +58,7 @@ interface Canvas {
function CanvasBoard({ canvas, onBack }: { canvas: Canvas; onBack: () => void }) {
const [cards, setCards] = useState<CanvasCard[]>(canvas.cards || []);
const [connections] = useState<CanvasConnection[]>(canvas.connections || []);
const [dragging, setDragging] = useState<string | null>(null);
const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });
const [viewport, setViewport] = useState(canvas.viewport || { x: 0, y: 0, zoom: 1 });
@@ -252,7 +253,7 @@ function CanvasBoard({ canvas, onBack }: { canvas: Canvas; onBack: () => void })
>
{/* Connections */}
<svg className="pointer-events-none absolute inset-0" style={{ width: 4000, height: 4000 }}>
{canvas.connections.map((conn) => {
{connections.map((conn) => {
const source = cards.find((c) => c.id === conn.source_card_id);
const target = cards.find((c) => c.id === conn.target_card_id);
if (!source || !target) return null;
@@ -129,7 +129,7 @@ export function BigCalendarWrapper({
eventPropGetter={eventStyleGetter}
onSelectEvent={handleSelectEvent}
views={['month', 'week', 'day']}
defaultView={defaultView}
view={defaultView}
date={date}
onNavigate={handleNavigate}
onView={handleViewChange}
@@ -6,13 +6,12 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { useRouter } from 'next/navigation';
import { toast } from 'sonner';
export function QuickCaptureWidget() {
const [type, setType] = useState('task');
const [title, setTitle] = useState('');
const [submitting, setSubmitting] = useState(false);
const router = useRouter();
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
@@ -20,34 +19,22 @@ export function QuickCaptureWidget() {
setSubmitting(true);
try {
const endpoint = type === 'task' ? '/api/tasks'
: type === 'habit' ? '/api/habits'
: '/api/notes';
const body: Record<string, unknown> = { title: title.trim() };
if (type === 'task') {
body.status = 'todo';
body.priority = 'medium';
}
if (type === 'habit') {
body.name = title.trim();
delete body.title;
body.frequency = 'daily';
body.difficulty = 'medium';
}
const res = await fetch(endpoint, {
const res = await fetch('/api/quick-capture', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
body: JSON.stringify({ type, text: title.trim() }),
});
if (res.ok) {
setTitle('');
router.refresh();
toast.success(type.charAt(0).toUpperCase() + type.slice(1) + ' created');
} else {
const err = await res.json().catch(() => ({ error: 'Unknown error' }));
toast.error(err.error || 'Failed to create');
}
} catch (err) {
console.error('Quick capture failed:', err);
toast.error('Failed to create');
} finally {
setSubmitting(false);
}
@@ -71,6 +58,7 @@ export function QuickCaptureWidget() {
<SelectItem value="task">Task</SelectItem>
<SelectItem value="habit">Habit</SelectItem>
<SelectItem value="note">Note</SelectItem>
<SelectItem value="project">Project</SelectItem>
</SelectContent>
</Select>
<Input
@@ -79,7 +67,7 @@ export function QuickCaptureWidget() {
placeholder="Quick add..."
className="flex-1"
/>
<Button type="submit" size="icon" disabled={submitting || !title.trim()}>
<Button type="button" size="icon" disabled={submitting || !title.trim()} onClick={handleSubmit}>
<Send className="h-4 w-4" />
</Button>
</form>