feat: complete Phase 3 — advanced features for Casera web app

Adds sharing (residence share codes, join, user management, .casera file
export/import), subscription status with feature comparison, notification
preferences with bell icon, profile settings (edit info, change password,
theme picker, delete account), onboarding wizard with create/join paths,
enhanced dashboard with stats cards, Recharts completion chart, recent
activity feed, and task report PDF download.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-03-03 09:31:29 -06:00
commit 5a50d77515
183 changed files with 34450 additions and 0 deletions
+61
View File
@@ -0,0 +1,61 @@
"use client";
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import * as residencesApi from '@/lib/api/residences';
import type { CreateResidenceRequest, UpdateResidenceRequest } from '@/lib/api/residences';
// ---------------------------------------------------------------------------
// Query hooks
// ---------------------------------------------------------------------------
export function useResidences() {
return useQuery({
queryKey: ['residences'],
queryFn: () => residencesApi.getMyResidences(),
});
}
export function useResidence(id: number) {
return useQuery({
queryKey: ['residences', id],
queryFn: () => residencesApi.getResidence(id),
enabled: !!id,
});
}
// ---------------------------------------------------------------------------
// Mutation hooks
// ---------------------------------------------------------------------------
export function useCreateResidence() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (data: CreateResidenceRequest) =>
residencesApi.createResidence(data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['residences'] });
},
});
}
export function useUpdateResidence(id: number) {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (data: UpdateResidenceRequest) =>
residencesApi.updateResidence(id, data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['residences'] });
queryClient.invalidateQueries({ queryKey: ['residences', id] });
},
});
}
export function useDeleteResidence() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (id: number) => residencesApi.deleteResidence(id),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['residences'] });
},
});
}