aboutsummaryrefslogtreecommitdiffstats
path: root/apps/web/lib
diff options
context:
space:
mode:
Diffstat (limited to 'apps/web/lib')
-rw-r--r--apps/web/lib/providers.tsx34
-rw-r--r--apps/web/lib/userLocalSettings/bookmarksLayout.tsx37
-rw-r--r--apps/web/lib/userLocalSettings/types.ts24
-rw-r--r--apps/web/lib/userLocalSettings/userLocalSettings.ts18
4 files changed, 99 insertions, 14 deletions
diff --git a/apps/web/lib/providers.tsx b/apps/web/lib/providers.tsx
index 60f30931..9c937281 100644
--- a/apps/web/lib/providers.tsx
+++ b/apps/web/lib/providers.tsx
@@ -1,9 +1,11 @@
"use client";
+import type { UserLocalSettings } from "@/lib/userLocalSettings/types";
import type { Session } from "next-auth";
import React, { useState } from "react";
import { ThemeProvider } from "@/components/theme-provider";
import { TooltipProvider } from "@/components/ui/tooltip";
+import { UserLocalSettingsCtx } from "@/lib/userLocalSettings/bookmarksLayout";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { httpBatchLink, loggerLink } from "@trpc/client";
import { SessionProvider } from "next-auth/react";
@@ -46,10 +48,12 @@ export default function Providers({
children,
session,
clientConfig,
+ userLocalSettings,
}: {
children: React.ReactNode;
session: Session | null;
clientConfig: ClientConfig;
+ userLocalSettings: UserLocalSettings;
}) {
const queryClient = getQueryClient();
@@ -72,20 +76,22 @@ export default function Providers({
return (
<ClientConfigCtx.Provider value={clientConfig}>
- <SessionProvider session={session}>
- <api.Provider client={trpcClient} queryClient={queryClient}>
- <QueryClientProvider client={queryClient}>
- <ThemeProvider
- attribute="class"
- defaultTheme="system"
- enableSystem
- disableTransitionOnChange
- >
- <TooltipProvider delayDuration={0}>{children}</TooltipProvider>
- </ThemeProvider>
- </QueryClientProvider>
- </api.Provider>
- </SessionProvider>
+ <UserLocalSettingsCtx.Provider value={userLocalSettings}>
+ <SessionProvider session={session}>
+ <api.Provider client={trpcClient} queryClient={queryClient}>
+ <QueryClientProvider client={queryClient}>
+ <ThemeProvider
+ attribute="class"
+ defaultTheme="system"
+ enableSystem
+ disableTransitionOnChange
+ >
+ <TooltipProvider delayDuration={0}>{children}</TooltipProvider>
+ </ThemeProvider>
+ </QueryClientProvider>
+ </api.Provider>
+ </SessionProvider>
+ </UserLocalSettingsCtx.Provider>
</ClientConfigCtx.Provider>
);
}
diff --git a/apps/web/lib/userLocalSettings/bookmarksLayout.tsx b/apps/web/lib/userLocalSettings/bookmarksLayout.tsx
new file mode 100644
index 00000000..424046b9
--- /dev/null
+++ b/apps/web/lib/userLocalSettings/bookmarksLayout.tsx
@@ -0,0 +1,37 @@
+"use client";
+
+import type { z } from "zod";
+import { createContext, useContext } from "react";
+
+import type { BookmarksLayoutTypes, zUserLocalSettings } from "./types";
+
+const defaultLayout: BookmarksLayoutTypes = "masonry";
+
+export const UserLocalSettingsCtx = createContext<
+ z.infer<typeof zUserLocalSettings>
+>({
+ bookmarkGridLayout: defaultLayout,
+});
+
+function useUserLocalSettings() {
+ return useContext(UserLocalSettingsCtx);
+}
+
+export function useBookmarkLayout() {
+ const settings = useUserLocalSettings();
+ return settings.bookmarkGridLayout;
+}
+
+export function bookmarkLayoutSwitch<T>(
+ layout: BookmarksLayoutTypes,
+ data: Record<BookmarksLayoutTypes, T>,
+) {
+ return data[layout];
+}
+
+export function useBookmarkLayoutSwitch<T>(
+ data: Record<BookmarksLayoutTypes, T>,
+) {
+ const layout = useBookmarkLayout();
+ return data[layout];
+}
diff --git a/apps/web/lib/userLocalSettings/types.ts b/apps/web/lib/userLocalSettings/types.ts
new file mode 100644
index 00000000..155469f5
--- /dev/null
+++ b/apps/web/lib/userLocalSettings/types.ts
@@ -0,0 +1,24 @@
+import { z } from "zod";
+
+export const USER_LOCAL_SETTINGS_COOKIE_NAME = "hoarder-user-local-settings";
+
+const zBookmarkGridLayout = z.enum(["grid", "list", "masonry"]);
+export type BookmarksLayoutTypes = z.infer<typeof zBookmarkGridLayout>;
+
+export const zUserLocalSettings = z.object({
+ bookmarkGridLayout: zBookmarkGridLayout.optional().default("masonry"),
+});
+
+export type UserLocalSettings = z.infer<typeof zUserLocalSettings>;
+
+export function parseUserLocalSettings(str: string | undefined) {
+ try {
+ return zUserLocalSettings.parse(JSON.parse(str ?? "{}"));
+ } catch (e) {
+ return undefined;
+ }
+}
+
+export function defaultUserLocalSettings() {
+ return zUserLocalSettings.parse({});
+}
diff --git a/apps/web/lib/userLocalSettings/userLocalSettings.ts b/apps/web/lib/userLocalSettings/userLocalSettings.ts
new file mode 100644
index 00000000..8b39d0d6
--- /dev/null
+++ b/apps/web/lib/userLocalSettings/userLocalSettings.ts
@@ -0,0 +1,18 @@
+"use server";
+
+import { cookies } from "next/headers";
+
+import type { BookmarksLayoutTypes } from "./types";
+import {
+ parseUserLocalSettings,
+ USER_LOCAL_SETTINGS_COOKIE_NAME,
+} from "./types";
+
+export async function updateBookmarksLayout(layout: BookmarksLayoutTypes) {
+ const userSettings = cookies().get(USER_LOCAL_SETTINGS_COOKIE_NAME);
+ const parsed = parseUserLocalSettings(userSettings?.value);
+ cookies().set(
+ USER_LOCAL_SETTINGS_COOKIE_NAME,
+ JSON.stringify({ ...parsed, bookmarkGridLayout: layout }),
+ );
+}