From c2566ec1600ff654efb5ce8cace1015c6d571a06 Mon Sep 17 00:00:00 2001 From: Shoubhit Dash Date: Sun, 10 Nov 2024 13:22:16 +0530 Subject: [PATCH] persist user preferences between sessions --- .../(tools)/rounded-border/rounded-tool.tsx | 8 +++-- src/app/(tools)/square-image/square-tool.tsx | 7 +++-- src/app/(tools)/svg-to-png/svg-tool.tsx | 3 +- src/hooks/use-local-storage.ts | 30 +++++++++++++++++++ 4 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 src/hooks/use-local-storage.ts diff --git a/src/app/(tools)/rounded-border/rounded-tool.tsx b/src/app/(tools)/rounded-border/rounded-tool.tsx index 20fb159..0f43646 100644 --- a/src/app/(tools)/rounded-border/rounded-tool.tsx +++ b/src/app/(tools)/rounded-border/rounded-tool.tsx @@ -2,6 +2,7 @@ import { usePlausible } from "next-plausible"; import { useMemo, useState } from "react"; import { ChangeEvent } from "react"; +import { useLocalStorage } from "@/hooks/use-local-storage"; import React from "react"; type Radius = 2 | 4 | 8 | 16 | 32 | 64; @@ -188,8 +189,11 @@ export function RoundedTool() { const { imageContent, imageMetadata, handleFileUpload, cancel } = useFileUploader(); - const [radius, setRadius] = useState(2); - const [background, setBackground] = useState("transparent"); + const [radius, setRadius] = useLocalStorage("roundedTool_radius", 2); + const [background, setBackground] = useLocalStorage( + "roundedTool_background", + "transparent" + ); if (!imageMetadata) return ( diff --git a/src/app/(tools)/square-image/square-tool.tsx b/src/app/(tools)/square-image/square-tool.tsx index 0d70be0..7739add 100644 --- a/src/app/(tools)/square-image/square-tool.tsx +++ b/src/app/(tools)/square-image/square-tool.tsx @@ -2,12 +2,13 @@ import React, { useState, useEffect, ChangeEvent } from "react"; import { usePlausible } from "next-plausible"; +import { useLocalStorage } from "@/hooks/use-local-storage"; export const SquareTool: React.FC = () => { const [imageFile, setImageFile] = useState(null); - const [backgroundColor, setBackgroundColor] = useState<"black" | "white">( - "white" - ); + const [backgroundColor, setBackgroundColor] = useLocalStorage< + "black" | "white" + >("squareTool_backgroundColor", "white"); const [previewUrl, setPreviewUrl] = useState(null); const [canvasDataUrl, setCanvasDataUrl] = useState(null); const [imageMetadata, setImageMetadata] = useState<{ diff --git a/src/app/(tools)/svg-to-png/svg-tool.tsx b/src/app/(tools)/svg-to-png/svg-tool.tsx index 9b62c44..6a8ddb3 100644 --- a/src/app/(tools)/svg-to-png/svg-tool.tsx +++ b/src/app/(tools)/svg-to-png/svg-tool.tsx @@ -1,6 +1,7 @@ "use client"; import { usePlausible } from "next-plausible"; import { useMemo, useState } from "react"; +import { useLocalStorage } from "@/hooks/use-local-storage"; import { ChangeEvent } from "react"; @@ -175,7 +176,7 @@ export function SVGTool() { const { svgContent, imageMetadata, handleFileUpload, cancel } = useFileUploader(); - const [scale, setScale] = useState(1); + const [scale, setScale] = useLocalStorage("svgTool_scale", 1); if (!imageMetadata) return ( diff --git a/src/hooks/use-local-storage.ts b/src/hooks/use-local-storage.ts new file mode 100644 index 0000000..8c1e39d --- /dev/null +++ b/src/hooks/use-local-storage.ts @@ -0,0 +1,30 @@ +import { useState } from "react"; + +export function useLocalStorage(key: string, initialValue: T) { + const [storedValue, setStoredValue] = useState(() => { + if (typeof window === "undefined") return initialValue; + + try { + const item = window.localStorage.getItem(key); + return item ? JSON.parse(item) : initialValue; + } catch (error) { + console.warn(`Error reading localStorage key "${key}":`, error); + return initialValue; + } + }); + + const setValue = (value: T | ((val: T) => T)) => { + try { + const valueToStore = + value instanceof Function ? value(storedValue) : value; + setStoredValue(valueToStore); + if (typeof window !== "undefined") { + window.localStorage.setItem(key, JSON.stringify(valueToStore)); + } + } catch (error) { + console.warn(`Error setting localStorage key "${key}":`, error); + } + }; + + return [storedValue, setValue] as const; +}