Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | 364x 127x 364x 364x 2678x 2678x 605x 2073x 2073x 1x 1x 2072x 2072x 2072x 364x 414x 414x 414x 414x 364x 42x 42x 364x 364x 378x 364x 4x 364x 364x 364x 360x 360x 360x 360x | import { merge } from "remeda";
import { z } from "zod";
import { LocalStorageState } from "client/types/reduxTypes";
import { ProgramType } from "shared/types/models/programItem";
import { StringToJsonSchema } from "client/utils/zodUtils";
import { ActiveProgramType } from "shared/config/clientConfigTypes";
import { getProgramTypeSelectOptions } from "client/utils/getProgramTypeSelectOptions";
import { Locale } from "shared/types/locale";
import {
browserStoragePrefix,
localStorageStateKey,
} from "shared/constants/browserStorage";
const isActive = (programType: ActiveProgramType): boolean =>
getProgramTypeSelectOptions().includes(programType);
const SessionSchema = z
.object({
login: z.object({ jwt: z.string() }).optional(),
admin: z
.object({
activeProgramTypes: z.array(z.enum(ProgramType).refine(isActive)),
})
.optional(),
})
.strict();
type LocalStorage = z.infer<typeof SessionSchema>;
export const loadSession = (): LocalStorage | undefined => {
const serializedValue = localStorage.getItem(localStorageStateKey);
if (!serializedValue) {
return undefined;
}
const parseJsonResult = StringToJsonSchema.safeParse(serializedValue);
if (!parseJsonResult.success) {
clearSession();
return undefined;
}
const result = SessionSchema.safeParse(parseJsonResult.data);
Iif (!result.success) {
clearSession();
return undefined;
}
return result.data;
};
export const saveSession = (state: Partial<LocalStorageState>): void => {
const previousSession = loadSession();
const newSession = previousSession ? merge(previousSession, state) : state;
const serializedState = JSON.stringify(newSession);
localStorage.setItem(localStorageStateKey, serializedState);
};
export const clearSession = (): void => {
localStorage.removeItem(localStorageStateKey);
sessionStorage.clear();
};
// Dismissed admin message is stored separately from the zod-strict 'state' object so a public
// (logged-out) visitor can remember their dismissal without a session. We store the dismissed
// message text itself, so a new or edited admin message no longer matches and shows again
const dismissedAdminMessageKey = `${browserStoragePrefix}-dismissedAdminMessage`;
export const getDismissedAdminMessage = (): string => {
return localStorage.getItem(dismissedAdminMessageKey) ?? "";
};
export const saveDismissedAdminMessage = (adminMessage: string): void => {
localStorage.setItem(dismissedAdminMessageKey, adminMessage);
};
// Locale uses same 'languageKey' as i18next but i18next has separate logic for handling localStorage
const languageKey = "i18nextLng";
const LanguageValueSchema = z.enum(Locale);
export const getLocalStorageLocale = (): string => {
const serializedValue = localStorage.getItem(languageKey);
const result = LanguageValueSchema.safeParse(serializedValue);
Iif (!result.success) {
localStorage.removeItem(languageKey);
location.reload();
return Locale.EN;
}
return result.data;
};
|