This repository has been archived on 2026-08-11. You can view files and clone it, but cannot push or open issues or pull requests.
Gishen-Mob/lib/stores/prescriptionStore.ts
kirukib 7310a349c5 Add Gishen mobile app with complete demo shopping and care flows.
Ship Expo Router screens, seeded stores, and polished UX so auth, shop, checkout, prescriptions, loyalty, family, and account processes work end-to-end offline.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-07 01:21:32 +03:00

166 lines
4.6 KiB
TypeScript

import AsyncStorage from "@react-native-async-storage/async-storage";
import { create } from "zustand";
import { createJSONStorage, persist } from "zustand/middleware";
import {
seedDoseLogs,
seedPrescriptions,
seedReminders,
} from "@/lib/data/seed";
export type RxStatus =
| "submitted"
| "under_review"
| "approved"
| "queried"
| "rejected"
| "filled";
export type LineStatus = "ready" | "review" | "unavailable";
export type Prescription = {
id: string;
patientName: string;
memberId?: string | null;
medicineName: string;
medicines: { name: string; status: LineStatus }[];
imageUris: string[];
daysSupply: number;
lastFilledAt: string | null;
status: RxStatus;
notes?: string;
createdAt: string;
};
export type Reminder = {
id: string;
prescriptionId: string;
medicineName: string;
times: string[];
daysOfWeek: number[];
graceMinutes: number;
escalateOnMiss: boolean;
memberId?: string | null;
enabled: boolean;
};
export type DoseLog = {
id: string;
reminderId: string;
scheduledAt: string;
status: "pending" | "taken" | "snoozed" | "missed_escalated";
confirmedAt?: string;
};
type RxState = {
prescriptions: Prescription[];
reminders: Reminder[];
doseLogs: DoseLog[];
draftImages: string[];
setDraftImages: (uris: string[]) => void;
addPrescription: (
p: Omit<Prescription, "id" | "createdAt" | "status">
) => Prescription;
updateRxStatus: (id: string, status: RxStatus) => void;
markRefilled: (id: string) => void;
removePrescription: (id: string) => void;
upsertReminder: (r: Omit<Reminder, "id"> & { id?: string }) => void;
removeReminder: (id: string) => void;
confirmDose: (logId: string) => void;
escalateDose: (logId: string) => void;
schedulePendingDose: (reminderId: string) => DoseLog;
};
export const usePrescriptionStore = create<RxState>()(
persist(
(set, get) => ({
prescriptions: seedPrescriptions,
reminders: seedReminders,
doseLogs: seedDoseLogs,
draftImages: [],
setDraftImages: (uris) => set({ draftImages: uris }),
addPrescription: (payload) => {
const rx: Prescription = {
...payload,
id: `rx_${Date.now()}`,
createdAt: new Date().toISOString(),
status: "submitted",
};
set({ prescriptions: [rx, ...get().prescriptions] });
return rx;
},
updateRxStatus: (id, status) =>
set({
prescriptions: get().prescriptions.map((p) =>
p.id === id ? { ...p, status } : p
),
}),
markRefilled: (id) =>
set({
prescriptions: get().prescriptions.map((p) =>
p.id === id
? { ...p, lastFilledAt: new Date().toISOString(), status: "filled" }
: p
),
}),
removePrescription: (id) =>
set({
prescriptions: get().prescriptions.filter((p) => p.id !== id),
reminders: get().reminders.filter((r) => r.prescriptionId !== id),
}),
upsertReminder: (r) => {
const id = r.id ?? `rem_${Date.now()}`;
const next = { ...r, id } as Reminder;
const others = get().reminders.filter((x) => x.id !== id);
set({ reminders: [next, ...others] });
},
removeReminder: (id) =>
set({ reminders: get().reminders.filter((r) => r.id !== id) }),
confirmDose: (logId) =>
set({
doseLogs: get().doseLogs.map((l) =>
l.id === logId
? {
...l,
status: "taken",
confirmedAt: new Date().toISOString(),
}
: l
),
}),
escalateDose: (logId) =>
set({
doseLogs: get().doseLogs.map((l) =>
l.id === logId ? { ...l, status: "missed_escalated" } : l
),
}),
schedulePendingDose: (reminderId) => {
const log: DoseLog = {
id: `dose_${Date.now()}`,
reminderId,
scheduledAt: new Date().toISOString(),
status: "pending",
};
set({ doseLogs: [log, ...get().doseLogs] });
return log;
},
}),
{
name: "gishen-prescriptions",
storage: createJSONStorage(() => AsyncStorage),
version: 2,
migrate: (persisted: unknown) => {
const state = (persisted ?? {}) as Partial<RxState>;
const empty = !state.prescriptions?.length;
return empty
? {
...state,
prescriptions: seedPrescriptions,
reminders: seedReminders,
doseLogs: seedDoseLogs,
}
: state;
},
}
)
);