- Add tier system migration (free/pro) - FamilyProvider with tier and memberCount - Ready for freemium model with limits Run migration: psql -f drizzle/0005_tier_system.sql Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
106 lines
No EOL
2.7 KiB
TypeScript
106 lines
No EOL
2.7 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useEffect, createContext, useContext } from "react";
|
|
import { ReactNode } from "react";
|
|
|
|
interface Child {
|
|
id: string;
|
|
name: string;
|
|
birthDate: string;
|
|
sex: string;
|
|
}
|
|
|
|
interface FamilyContextType {
|
|
familyId: string | null;
|
|
childId: string | null;
|
|
child: Child | null;
|
|
children: Child[];
|
|
loading: boolean;
|
|
tier: "free" | "pro";
|
|
memberCount: number;
|
|
}
|
|
|
|
const FamilyContext = createContext<FamilyContextType>({
|
|
familyId: null,
|
|
childId: null,
|
|
child: null,
|
|
children: [],
|
|
loading: true,
|
|
tier: "free",
|
|
memberCount: 2,
|
|
});
|
|
|
|
export function useFamily() {
|
|
return useContext(FamilyContext);
|
|
}
|
|
|
|
export function FamilyProvider({ children: providerChildren }: { children: ReactNode }) {
|
|
const [familyId, setFamilyId] = useState<string | null>(null);
|
|
const [childId, setChildId] = useState<string | null>(null);
|
|
const [child, setChild] = useState<Child | null>(null);
|
|
const [children, setChildren] = useState<Child[]>([]);
|
|
const [loading, setLoading] = useState(true);
|
|
const [tier, setTier] = useState<"free" | "pro">("free");
|
|
const [memberCount, setMemberCount] = useState(2);
|
|
|
|
useEffect(() => {
|
|
async function fetchFamilyData() {
|
|
try {
|
|
const res = await fetch("/api/children?familyId=default");
|
|
const data = await res.json();
|
|
|
|
if (data.children?.length > 0) {
|
|
const childList = data.children.map((c: any) => ({
|
|
id: c.id,
|
|
name: c.name,
|
|
birthDate: c.birthDate,
|
|
sex: c.sex,
|
|
}));
|
|
|
|
setChildren(childList);
|
|
setChild(childList[0]);
|
|
setChildId(childList[0].id);
|
|
}
|
|
|
|
setFamilyId("default");
|
|
setTier("free");
|
|
setMemberCount(2);
|
|
} catch (err) {
|
|
console.error("Failed to fetch family:", err);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}
|
|
|
|
fetchFamilyData();
|
|
}, []);
|
|
|
|
// Check if can add more children/members based on tier limits
|
|
const canAddChild = () => memberCount < 2 || tier === "pro"; // free = 1 child, pro = unlimited
|
|
const canAddMember = () => memberCount < 2 && tier === "free" ? false : true;
|
|
|
|
return (
|
|
<FamilyContext.Provider
|
|
value={{
|
|
familyId,
|
|
childId,
|
|
child,
|
|
children,
|
|
loading,
|
|
tier,
|
|
memberCount,
|
|
}}
|
|
>
|
|
{providerChildren}
|
|
</FamilyContext.Provider>
|
|
);
|
|
}
|
|
|
|
// Note: Call useFamily() in any page to get:
|
|
// - familyId: The current family ID
|
|
// - childId: The selected child ID
|
|
// - child: The selected child object
|
|
// - children: List of all children
|
|
// - loading: Whether data is loading
|
|
// - tier: "free" or "pro"
|
|
// - memberCount: Number of family members
|