feat: allow dashboard section reordering

This commit is contained in:
zv
2026-07-04 20:31:56 +02:00
parent 91acdb39b8
commit c7da9e0d94
7 changed files with 209 additions and 34 deletions

View File

@@ -12,9 +12,12 @@ import {
type AppSectionVisibility,
} from "@/lib/app-sections";
import {
DEFAULT_DASHBOARD_SECTION_ORDER,
DEFAULT_DASHBOARD_SECTION_VISIBILITY,
normalizeDashboardSectionOrder,
normalizeDashboardSectionVisibility,
type DashboardSectionId,
type DashboardSectionOrder,
type DashboardSectionVisibility,
} from "@/lib/dashboard-sections";
import {
@@ -49,6 +52,7 @@ interface WeatherStore {
pressureUnit: PressureUnit;
distanceUnit: DistanceUnit;
dashboardSections: DashboardSectionVisibility;
dashboardSectionOrder: DashboardSectionOrder;
appSections: AppSectionVisibility;
toggleFavorite: (id: string) => void;
selectStation: (id: string) => void;
@@ -64,6 +68,7 @@ interface WeatherStore {
setPressureUnit: (unit: PressureUnit) => void;
setDistanceUnit: (unit: DistanceUnit) => void;
setDashboardSectionVisible: (section: DashboardSectionId, visible: boolean) => void;
moveDashboardSection: (section: DashboardSectionId, direction: -1 | 1) => void;
setAppSectionVisible: (section: AppSectionId, visible: boolean) => void;
}
@@ -84,6 +89,7 @@ export const useWeatherStore = create<WeatherStore>()(
pressureUnit: DEFAULT_PRESSURE_UNIT,
distanceUnit: DEFAULT_DISTANCE_UNIT,
dashboardSections: DEFAULT_DASHBOARD_SECTION_VISIBILITY,
dashboardSectionOrder: DEFAULT_DASHBOARD_SECTION_ORDER,
appSections: DEFAULT_APP_SECTION_VISIBILITY,
toggleFavorite: (id) =>
set((state) => ({
@@ -107,6 +113,16 @@ export const useWeatherStore = create<WeatherStore>()(
set((state) => ({
dashboardSections: { ...state.dashboardSections, [section]: visible },
})),
moveDashboardSection: (section, direction) =>
set((state) => {
const order = normalizeDashboardSectionOrder(state.dashboardSectionOrder);
const index = order.indexOf(section);
const nextIndex = index + direction;
if (index === -1 || nextIndex < 0 || nextIndex >= order.length) return state;
const nextOrder = [...order];
[nextOrder[index], nextOrder[nextIndex]] = [nextOrder[nextIndex], nextOrder[index]];
return { dashboardSectionOrder: nextOrder };
}),
setAppSectionVisible: (section, visible) =>
set((state) => ({
appSections: { ...state.appSections, [section]: visible },
@@ -122,6 +138,7 @@ export const useWeatherStore = create<WeatherStore>()(
| undefined;
if (!state) return persisted;
const dashboardSections = normalizeDashboardSectionVisibility(state.dashboardSections);
const dashboardSectionOrder = normalizeDashboardSectionOrder(state.dashboardSectionOrder);
const appSections = normalizeAppSectionVisibility(state.appSections);
const unitPreferences = {
temperatureUnit: isTemperatureUnit(state.temperatureUnit) ? state.temperatureUnit : DEFAULT_TEMPERATURE_UNIT,
@@ -132,13 +149,14 @@ export const useWeatherStore = create<WeatherStore>()(
pressureUnit: isPressureUnit(state.pressureUnit) ? state.pressureUnit : DEFAULT_PRESSURE_UNIT,
distanceUnit: isDistanceUnit(state.distanceUnit) ? state.distanceUnit : DEFAULT_DISTANCE_UNIT,
};
if (!location) return { ...state, ...unitPreferences, dashboardSections, appSections };
if (!location) return { ...state, ...unitPreferences, dashboardSections, dashboardSectionOrder, appSections };
const countryCode = location.countryCode ?? (location.province ? "PL" : null);
const region = location.region ?? getWeatherRegionForCountryCode(countryCode);
return {
...state,
...unitPreferences,
dashboardSections,
dashboardSectionOrder,
appSections,
selectedLocation: {
...location,