mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-11-01 18:19:43 +00:00
Add show all intensities toggle on packs page
This commit is contained in:
1 parent
a0049b7f8a
commit
b8c271cce1
2 files changed
+166
-102
No files matched your search
+110
-100
@@ -1,7 +1,7 @@
|
||||
import { create } from "zustand";
|
||||
import { supabase } from "../lib/supabase";
|
||||
import { Events } from "../lib/analytics";
|
||||
import type { QuestionPack, Category } from "@/types";
|
||||
import { create } from "zustand";
|
||||
import { supabase } from "../lib/supabase";
|
||||
import { Events } from "../lib/analytics";
|
||||
import type { QuestionPack, Category } from "@/types";
|
||||
import { useAuthStore } from "./authStore";
|
||||
|
||||
const DEFAULT_MAX_INTENSITY = 2;
|
||||
@@ -21,30 +21,34 @@ const getUserMaxIntensity = () => {
|
||||
};
|
||||
|
||||
interface PacksState {
|
||||
packs: QuestionPack[];
|
||||
categories: Category[];
|
||||
enabledPackIds: string[];
|
||||
isLoading: boolean;
|
||||
fetchPacks: () => Promise<void>;
|
||||
fetchEnabledPacks: () => Promise<void>;
|
||||
ensureEnabledPacksLoaded: () => Promise<void>;
|
||||
togglePack: (packId: string) => Promise<{ success: boolean; reason?: string }>;
|
||||
clearPacks: () => void;
|
||||
}
|
||||
|
||||
export const usePacksStore = create<PacksState>((set, get) => ({
|
||||
packs: [],
|
||||
categories: [],
|
||||
enabledPackIds: [],
|
||||
isLoading: false,
|
||||
|
||||
fetchPacks: async () => {
|
||||
set({ isLoading: true });
|
||||
|
||||
packs: QuestionPack[];
|
||||
categories: Category[];
|
||||
enabledPackIds: string[];
|
||||
isLoading: boolean;
|
||||
showAllIntensities: boolean;
|
||||
fetchPacks: () => Promise<void>;
|
||||
fetchEnabledPacks: () => Promise<void>;
|
||||
ensureEnabledPacksLoaded: () => Promise<void>;
|
||||
togglePack: (packId: string) => Promise<{ success: boolean; reason?: string }>;
|
||||
setShowAllIntensities: (value: boolean) => void;
|
||||
clearPacks: () => void;
|
||||
}
|
||||
|
||||
export const usePacksStore = create<PacksState>((set, get) => ({
|
||||
packs: [],
|
||||
categories: [],
|
||||
enabledPackIds: [],
|
||||
isLoading: false,
|
||||
showAllIntensities: false,
|
||||
|
||||
fetchPacks: async () => {
|
||||
set({ isLoading: true });
|
||||
|
||||
// Get user's max intensity preference
|
||||
const maxIntensity = getUserMaxIntensity();
|
||||
const showAllIntensities = get().showAllIntensities;
|
||||
|
||||
|
||||
|
||||
// Fetch categories
|
||||
const { data: categories } = await supabase
|
||||
.from("categories")
|
||||
@@ -62,8 +66,8 @@ export const usePacksStore = create<PacksState>((set, get) => ({
|
||||
.eq("is_public", true)
|
||||
.order("sort_order");
|
||||
|
||||
// Filter out packs above user's intensity preference
|
||||
if (maxIntensity < 5) {
|
||||
// Filter out packs above user's intensity preference (unless showing all)
|
||||
if (maxIntensity < 5 && !showAllIntensities) {
|
||||
query = query.or(`max_intensity.is.null,max_intensity.lte.${maxIntensity}`);
|
||||
}
|
||||
|
||||
@@ -86,76 +90,82 @@ export const usePacksStore = create<PacksState>((set, get) => ({
|
||||
isLoading: false
|
||||
});
|
||||
},
|
||||
|
||||
fetchEnabledPacks: async () => {
|
||||
const coupleId = useAuthStore.getState().user?.couple_id;
|
||||
if (!coupleId) {
|
||||
set({ enabledPackIds: [] });
|
||||
return;
|
||||
}
|
||||
|
||||
const { data: couplePacks } = await supabase
|
||||
.from("couple_packs")
|
||||
.select("pack_id")
|
||||
.eq("couple_id", coupleId)
|
||||
.eq("enabled", true);
|
||||
|
||||
const ids = couplePacks?.map(cp => cp.pack_id) || [];
|
||||
set({ enabledPackIds: ids });
|
||||
},
|
||||
|
||||
ensureEnabledPacksLoaded: async () => {
|
||||
// Only fetch if not already loaded - lightweight check for swipe screen
|
||||
const coupleId = useAuthStore.getState().user?.couple_id;
|
||||
if (!coupleId) return;
|
||||
|
||||
if (get().enabledPackIds.length === 0) {
|
||||
await get().fetchEnabledPacks();
|
||||
}
|
||||
},
|
||||
|
||||
togglePack: async (packId: string): Promise<{ success: boolean; reason?: string }> => {
|
||||
const coupleId = useAuthStore.getState().user?.couple_id;
|
||||
if (!coupleId) {
|
||||
return { success: false, reason: "no_couple" };
|
||||
}
|
||||
|
||||
const isEnabled = get().enabledPackIds.includes(packId);
|
||||
const newValue = !isEnabled;
|
||||
|
||||
// Optimistic update
|
||||
const newIds = newValue
|
||||
? [...get().enabledPackIds, packId]
|
||||
: get().enabledPackIds.filter(id => id !== packId);
|
||||
|
||||
set({ enabledPackIds: newIds });
|
||||
|
||||
const { error } = await supabase
|
||||
.from("couple_packs")
|
||||
.upsert({
|
||||
couple_id: coupleId,
|
||||
pack_id: packId,
|
||||
enabled: newValue
|
||||
});
|
||||
|
||||
if (error) {
|
||||
console.error("Error toggling pack:", error);
|
||||
// Revert by refetching
|
||||
get().fetchEnabledPacks();
|
||||
return { success: false, reason: "error" };
|
||||
}
|
||||
|
||||
// Track pack enable/disable
|
||||
if (newValue) {
|
||||
Events.packEnabled(packId);
|
||||
} else {
|
||||
Events.packDisabled(packId);
|
||||
}
|
||||
|
||||
return { success: true };
|
||||
},
|
||||
|
||||
clearPacks: () => {
|
||||
set({ enabledPackIds: [] });
|
||||
},
|
||||
}));
|
||||
|
||||
fetchEnabledPacks: async () => {
|
||||
const coupleId = useAuthStore.getState().user?.couple_id;
|
||||
if (!coupleId) {
|
||||
set({ enabledPackIds: [] });
|
||||
return;
|
||||
}
|
||||
|
||||
const { data: couplePacks } = await supabase
|
||||
.from("couple_packs")
|
||||
.select("pack_id")
|
||||
.eq("couple_id", coupleId)
|
||||
.eq("enabled", true);
|
||||
|
||||
const ids = couplePacks?.map(cp => cp.pack_id) || [];
|
||||
set({ enabledPackIds: ids });
|
||||
},
|
||||
|
||||
ensureEnabledPacksLoaded: async () => {
|
||||
// Only fetch if not already loaded - lightweight check for swipe screen
|
||||
const coupleId = useAuthStore.getState().user?.couple_id;
|
||||
if (!coupleId) return;
|
||||
|
||||
if (get().enabledPackIds.length === 0) {
|
||||
await get().fetchEnabledPacks();
|
||||
}
|
||||
},
|
||||
|
||||
togglePack: async (packId: string): Promise<{ success: boolean; reason?: string }> => {
|
||||
const coupleId = useAuthStore.getState().user?.couple_id;
|
||||
if (!coupleId) {
|
||||
return { success: false, reason: "no_couple" };
|
||||
}
|
||||
|
||||
const isEnabled = get().enabledPackIds.includes(packId);
|
||||
const newValue = !isEnabled;
|
||||
|
||||
// Optimistic update
|
||||
const newIds = newValue
|
||||
? [...get().enabledPackIds, packId]
|
||||
: get().enabledPackIds.filter(id => id !== packId);
|
||||
|
||||
set({ enabledPackIds: newIds });
|
||||
|
||||
const { error } = await supabase
|
||||
.from("couple_packs")
|
||||
.upsert({
|
||||
couple_id: coupleId,
|
||||
pack_id: packId,
|
||||
enabled: newValue
|
||||
});
|
||||
|
||||
if (error) {
|
||||
console.error("Error toggling pack:", error);
|
||||
// Revert by refetching
|
||||
get().fetchEnabledPacks();
|
||||
return { success: false, reason: "error" };
|
||||
}
|
||||
|
||||
// Track pack enable/disable
|
||||
if (newValue) {
|
||||
Events.packEnabled(packId);
|
||||
} else {
|
||||
Events.packDisabled(packId);
|
||||
}
|
||||
|
||||
return { success: true };
|
||||
},
|
||||
|
||||
setShowAllIntensities: (value: boolean) => {
|
||||
set({ showAllIntensities: value });
|
||||
// Refetch packs with new filter setting
|
||||
get().fetchPacks();
|
||||
},
|
||||
|
||||
clearPacks: () => {
|
||||
set({ enabledPackIds: [] });
|
||||
},
|
||||
}));
|
||||
Reference in new issue
Block a user