Skip to content

Commit

Permalink
feat: implement local storage for task management and enhance TaskCar…
Browse files Browse the repository at this point in the history
…d styling
  • Loading branch information
hasib-devs committed Nov 24, 2024
1 parent 94b60ed commit 6012160
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/components/TaskCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const TaskCard = ({ status }: Props) => {

const onDropOverStyle = () => {
return {
border: isOver ? "1px dashed black" : undefined,
border: isOver || !tasks.length ? "1px dashed black" : undefined,
opacity: isOver ? 0.8 : 1,
};
};
Expand Down
10 changes: 5 additions & 5 deletions src/contexts/task-context.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createContext, FC, ReactNode, useState } from "react";
import { TaskCreateType, TaskStatus, TaskType } from "../types";
import { useLocalStorage } from "../hooks";

type TaskContextType = {
tasks: TaskType[];
Expand All @@ -15,7 +16,7 @@ export const TaskContext = createContext<TaskContextType | undefined>(
);

export const TaskProvider: FC<{ children: ReactNode }> = ({ children }) => {
const [tasks, setTasks] = useState<TaskType[]>([
const [tasks, setTasks] = useLocalStorage<TaskType[]>("tasks", [
{
id: 1,
name: "Task One",
Expand Down Expand Up @@ -53,10 +54,9 @@ export const TaskProvider: FC<{ children: ReactNode }> = ({ children }) => {
}

function moveTask(task: TaskType, status: TaskStatus) {
const newTasks = tasks.map((t) =>
t.id === task.id ? { ...t, status } : t
);
setTasks(newTasks);
setTasks((prevTasks) => {
return prevTasks.map((t) => (t.id === task.id ? { ...t, status } : t));
});
}

function createTask(task: TaskCreateType) {
Expand Down
53 changes: 50 additions & 3 deletions src/hooks/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,57 @@
import { useContext } from "react";
import {
Dispatch,
SetStateAction,
useContext,
useEffect,
useRef,
useState,
} from "react";
import { TaskContext } from "../contexts/task-context";

export const useTaskContext = () => {
export function useTaskContext() {
const context = useContext(TaskContext);
if (!context) {
throw new Error("useTaskContext must be used within a TaskProvider");
}
return context;
};
}

type InitialValueType<T> = T | (() => T);

export function useLocalStorage<T>(
key: string,
initialValue: InitialValueType<T>,
{ serialize = JSON.stringify, deserialize = JSON.parse } = {}
): [T, Dispatch<SetStateAction<T>>] {
const [storedValue, setStoredValue] = useState<T>(() => {
try {
const item = window.localStorage.getItem(key);
if (item) {
return deserialize(item);
}

return initialValue instanceof Function ? initialValue() : initialValue;
} catch (error) {
console.error(error);
return initialValue;
}
});

const prevKeyRef = useRef(key);

// Use useEffect to update localstorage when value changes
useEffect(() => {
try {
if (prevKeyRef.current !== key) {
window.localStorage.removeItem(prevKeyRef.current);
}

prevKeyRef.current = key;
window.localStorage.setItem(key, serialize(storedValue));
} catch (error) {
console.error(error);
}
}, [storedValue, serialize, key]);

return [storedValue, setStoredValue];
}

0 comments on commit 6012160

Please sign in to comment.