Skip to content

Commit e4b7448

Browse files
authored
fix(offline): make the app a pwa (#16)
* feat(voting): remove offline voting * feat(notes): remove offline notes * feat(offline): remove offline * fix(offline): cache data and pages * chore(deps): remove unused packages * chore(deps): remove pnpm-lock * fix(sets): is multi artist for single artist * fix(set): show social links for single artist * feat(github): add rules for function hoisting
1 parent 919e6ab commit e4b7448

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+588
-2404
lines changed

.claude/settings.local.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
"mcp__ide__getDiagnostics",
1717
"Bash(git checkout:*)",
1818
"Bash(mkdir:*)",
19-
"Bash(npx oxlint:*)"
19+
"Bash(npx oxlint:*)",
20+
"WebSearch",
21+
"WebFetch(domain:tanstack.com)",
22+
"Bash(node:*)"
2023
],
2124
"deny": []
2225
}

.github/copilot-instructions.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Copilot Custom Instructions
2+
3+
see CLAUDE.md for more details and rules.
4+
5+
## Function Definitions After Return in React Components
6+
7+
In this codebase, it is acceptable and preferred to define helper functions (such as event handlers) after the main component’s return statement. This style improves readability by keeping the primary component logic at the top and allowing additional details to be found below. JavaScript and TypeScript support function hoisting for function declarations, so this pattern is safe and intentional. Please do not flag this as a style issue in reviews.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,4 @@ tests/screenshots/
3535
supabase/.temp
3636
supabase/.branches
3737
.vercel
38+
dev-dist

CLAUDE.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ src/
114114
- **Forms**: ALL forms must use react-hook-form with proper validation. Never use plain HTML forms or manual state management for form inputs. Use @hookform/resolvers for validation schemas when needed.
115115
- **Long Components**: Break long components (>150 lines) into smaller focused pieces. Follow the FilterSortControls pattern of primary controls + expandable sections.
116116

117+
#### Function Definitions After Return in React Components
118+
119+
In this codebase, it is acceptable and preferred to define helper functions (such as event handlers) after the main component’s return statement. This style improves readability by keeping the primary component logic at the top and allowing additional details to be found below. JavaScript and TypeScript support function hoisting for function declarations, so this pattern is safe and intentional. Please do not flag this as a style issue in reviews.
120+
117121
### Important Notes
118122

119123
- Server runs on port 8080 (not standard 3000)

package-lock.json

Lines changed: 75 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,10 @@
5555
"@radix-ui/react-tooltip": "^1.1.4",
5656
"@supabase/supabase-js": "^2.50.0",
5757
"@tailwindcss/line-clamp": "^0.4.4",
58+
"@tanstack/query-async-storage-persister": "^5.86.0",
5859
"@tanstack/react-query": "^5.56.2",
5960
"@tanstack/react-query-devtools": "^5.81.2",
61+
"@tanstack/react-query-persist-client": "^5.85.9",
6062
"class-variance-authority": "^0.7.1",
6163
"clsx": "^2.1.1",
6264
"cmdk": "^1.0.0",

src/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Toaster as Sonner } from "@/components/ui/sonner";
33
import { TooltipProvider } from "@/components/ui/tooltip";
44
import { BrowserRouter } from "react-router-dom";
55
import { CookieConsentBanner } from "@/components/layout/legal/CookieConsentBanner";
6+
import { OfflineIndicator } from "@/components/ui/OfflineIndicator";
67
import {
78
getSubdomainInfo,
89
shouldRedirectFromWww,
@@ -40,6 +41,7 @@ function App() {
4041
</FestivalEditionProvider>
4142
</AuthProvider>
4243
</BrowserRouter>
44+
<OfflineIndicator />
4345
</TooltipProvider>
4446
);
4547
}

src/components/router/EditionRoutes.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { MapTab } from "@/pages/EditionView/tabs/MapTab";
88
import { InfoTab } from "@/pages/EditionView/tabs/InfoTab";
99
import { SocialTab } from "@/pages/EditionView/tabs/SocialTab";
1010
import { ScheduleTabTimeline } from "@/pages/EditionView/tabs/ScheduleTab/TimelineTab";
11-
import { ScheduleTabList } from "@/pages/EditionView/tabs/ScheduleTab/ListTab";
11+
import { ScheduleTabList } from "@/pages/EditionView/tabs/ScheduleTab/list/ListTab";
1212
import { ScheduleTab } from "@/pages/EditionView/tabs/ScheduleTab";
1313

1414
interface EditionRoutesProps {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { useOnlineStatus } from "@/hooks/useOnlineStatus";
2+
import { Badge } from "@/components/ui/badge";
3+
import { WifiOff } from "lucide-react";
4+
5+
export function OfflineIndicator() {
6+
const isOnline = useOnlineStatus();
7+
8+
if (isOnline) return null;
9+
10+
return (
11+
<Badge variant="destructive" className="fixed top-4 right-4 z-50 gap-1">
12+
<WifiOff size={12} />
13+
Offline
14+
</Badge>
15+
);
16+
}

src/contexts/AuthContext.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {
99
import { User } from "@supabase/supabase-js";
1010
import { supabase } from "@/integrations/supabase/client";
1111
import { useProfileQuery } from "@/hooks/queries/auth/useProfile";
12-
import { profileOfflineService } from "@/services/profileOfflineService";
1312
import { useToast } from "@/hooks/use-toast";
1413
import { AuthDialog } from "@/components/AuthDialog/AuthDialog";
1514
import { Profile } from "@/hooks/queries/auth/useProfile";
@@ -60,7 +59,7 @@ export function AuthProvider({ children }: AuthProviderProps) {
6059
if (event === "SIGNED_OUT") {
6160
// For sign out, use the current user state from closure
6261
if (user?.id) {
63-
await profileOfflineService.clearCachedProfile(user.id);
62+
// await profileOfflineService.clearCachedProfile(user.id);
6463
}
6564
}
6665

@@ -127,7 +126,7 @@ export function AuthProvider({ children }: AuthProviderProps) {
127126
async function signOut() {
128127
// Clear cached profile before signing out
129128
if (user?.id) {
130-
await profileOfflineService.clearCachedProfile(user.id);
129+
// await profileOfflineService.clearCachedProfile(user.id);
131130
}
132131
await supabase.auth.signOut();
133132
}

0 commit comments

Comments
 (0)