feat(dashboard): setting up layout
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
import { TZDate } from "@date-fns/tz";
|
||||
import { eachDayOfInterval, endOfMonth, endOfWeek, startOfMonth, startOfWeek } from "date-fns";
|
||||
|
||||
export function useCalendarDates(currentDate: Date, weekStartsOnMonday: boolean) {
|
||||
const monthStart = startOfMonth(currentDate);
|
||||
const monthEnd = endOfMonth(currentDate);
|
||||
const calendarStart = startOfWeek(monthStart, {
|
||||
weekStartsOn: weekStartsOnMonday ? 1 : 0,
|
||||
});
|
||||
const calendarEnd = endOfWeek(monthEnd, {
|
||||
weekStartsOn: weekStartsOnMonday ? 1 : 0,
|
||||
});
|
||||
const calendarDays = eachDayOfInterval({
|
||||
end: calendarEnd,
|
||||
start: calendarStart,
|
||||
}).map((date) => new TZDate(date, "UTC"));
|
||||
const firstWeek = eachDayOfInterval({
|
||||
end: endOfWeek(calendarStart, { weekStartsOn: weekStartsOnMonday ? 1 : 0 }),
|
||||
start: calendarStart,
|
||||
}).map((date) => new TZDate(date, "UTC"));
|
||||
|
||||
return {
|
||||
calendarDays,
|
||||
calendarEnd,
|
||||
calendarStart,
|
||||
firstWeek,
|
||||
monthEnd,
|
||||
monthStart,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
// Original useLocalStorage hook (useState-like API)
|
||||
export function useLocalStorage<T>(
|
||||
key: string,
|
||||
initialValue: T,
|
||||
): [T, (value: T | ((val: T) => T)) => void] {
|
||||
// Initialize state with a function to handle SSR
|
||||
const [localState, setLocalState] = useState<T>(() => {
|
||||
// Check if we're in a browser environment
|
||||
if (typeof window === "undefined") {
|
||||
return initialValue;
|
||||
}
|
||||
|
||||
try {
|
||||
// Get from local storage by key
|
||||
const item = window.localStorage.getItem(key);
|
||||
// Parse stored json or if none return initialValue
|
||||
return item ? JSON.parse(item) : initialValue;
|
||||
} catch (error) {
|
||||
console.warn(`Error reading localStorage key "${key}":`, error);
|
||||
return initialValue;
|
||||
}
|
||||
});
|
||||
|
||||
// Return a wrapped version of useState's setter function that persists the new value to localStorage
|
||||
const handleSetState = useCallback(
|
||||
(value: T | ((val: T) => T)) => {
|
||||
try {
|
||||
// Allow value to be a function so we have same API as useState
|
||||
const valueToStore = value instanceof Function ? value(localState) : value;
|
||||
// Save state
|
||||
setLocalState(valueToStore);
|
||||
// Save to local storage
|
||||
if (typeof window !== "undefined") {
|
||||
window.localStorage.setItem(key, JSON.stringify(valueToStore));
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`Error setting localStorage key "${key}":`, error);
|
||||
}
|
||||
},
|
||||
[key, localState],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
// Handle storage changes in other tabs/windows
|
||||
function handleStorageChange(event: StorageEvent) {
|
||||
if (event.key === key && event.newValue) {
|
||||
setLocalState(JSON.parse(event.newValue));
|
||||
}
|
||||
}
|
||||
|
||||
// Subscribe to storage changes
|
||||
if (typeof window !== "undefined") {
|
||||
window.addEventListener("storage", handleStorageChange);
|
||||
}
|
||||
|
||||
// Cleanup the event listener on component unmount
|
||||
return () => {
|
||||
if (typeof window !== "undefined") {
|
||||
window.removeEventListener("storage", handleStorageChange);
|
||||
}
|
||||
};
|
||||
}, [key]);
|
||||
|
||||
return [localState, handleSetState];
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/** biome-ignore-all lint/suspicious/noExplicitAny: This is a hook file */
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { type Resolver, type UseFormProps, useForm } from "react-hook-form";
|
||||
import type { z } from "zod";
|
||||
|
||||
export const useZodForm = <T extends z.ZodType<any, any>>(
|
||||
schema: T,
|
||||
options?: Omit<UseFormProps<z.infer<T>>, "resolver">,
|
||||
) => {
|
||||
return useForm<z.infer<T>>({
|
||||
resolver: zodResolver(schema) as unknown as Resolver<z.infer<T>, any, z.infer<T>>,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user