diff --git a/todoblue/package.json b/todoblue/package.json
index 0657e6b..802d7b6 100644
--- a/todoblue/package.json
+++ b/todoblue/package.json
@@ -23,6 +23,7 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"server-only": "^0.0.1",
- "typescript": "5.1.6"
+ "typescript": "5.1.6",
+ "use-local-storage": "^3.0.0"
}
}
diff --git a/todoblue/src/app/RootMain.tsx b/todoblue/src/app/RootMain.tsx
index 2b16623..ec2e95e 100644
--- a/todoblue/src/app/RootMain.tsx
+++ b/todoblue/src/app/RootMain.tsx
@@ -1,6 +1,7 @@
import {CreatePrivateBoardPanel} from "@/app/CreatePrivateBoardPanel"
import {CreatePublicBoardPanel} from "@/app/CreatePublicBoardPanel"
import style from "@/app/page.module.css"
+import {StarredBoardsPanel} from "@/app/StarredBoardsPanel"
import {default as React} from "react"
@@ -14,6 +15,12 @@ export function RootMain() {
+
+
+ Usa un tabellone giĆ esistente
+
+
+
)
}
diff --git a/todoblue/src/app/StarContext.tsx b/todoblue/src/app/StarContext.tsx
new file mode 100644
index 0000000..fde32ad
--- /dev/null
+++ b/todoblue/src/app/StarContext.tsx
@@ -0,0 +1,57 @@
+"use client";
+
+import {createContext, Dispatch, ReactNode, SetStateAction, useCallback, useContext} from "react"
+import useLocalStorage from "use-local-storage"
+
+export interface StarContextData {
+ starred: string[],
+ setStarred: Dispatch>
+ addStarred: (key: string) => void,
+ removeStarred: (key: string) => void,
+}
+
+const StarContext = createContext(null)
+
+export function StarredManager({children}: {children: ReactNode}) {
+ const [starred, setStarred] = useLocalStorage("TODOBLUE_STARRED", [])
+
+ const addStarred = useCallback((value: string) => {
+ setStarred(prev => {
+ if(!prev) {
+ return [value]
+ }
+ else {
+ return [...prev, value]
+ }
+ })
+ }, [])
+
+ const removeStarred = useCallback((value: string) => {
+ setStarred(prev => {
+ if(!prev) {
+ return []
+ }
+ else {
+ const result = [...prev]
+ delete result[result.indexOf(value)]
+ return result
+ }
+ })
+ }, [])
+
+ return (
+
+ {children}
+
+ )
+}
+
+export function useManagedStarred(): StarContextData {
+ const context = useContext(StarContext)
+
+ if(context === null) {
+ throw new Error("useStarContext used outside a StarContext.")
+ }
+
+ return context
+}
diff --git a/todoblue/src/app/StarredBoardsPanel.tsx b/todoblue/src/app/StarredBoardsPanel.tsx
new file mode 100644
index 0000000..c387b4f
--- /dev/null
+++ b/todoblue/src/app/StarredBoardsPanel.tsx
@@ -0,0 +1,52 @@
+"use client";
+
+import {useManagedStarred} from "@/app/StarContext"
+import cn from "classnames"
+import Link from "next/link"
+import {useEffect, useState} from "react"
+
+
+export function StarredBoardsPanel() {
+ const [isClient, setIsClient] = useState(null);
+ const {starred} = useManagedStarred()
+
+ useEffect(() => setIsClient(true), [])
+
+ let content;
+ if(!isClient) {
+ content = <>
+
+ Sto recuperando i dati salvati sul tuo browser...
+
+ >
+ }
+ else {
+ content = <>
+
+ Puoi stellare un tabellone cliccando sulla stellina una volta che ci sei dentro.
+
+ {starred.length > 0 ?
+
+ {starred.map(s => {s}
)}
+
+ :
+
+ Non hai ancora stellato nessun tabellone.
+
+ }
+ >
+ }
+
+ return (
+
+
+ Tabelloni stellati
+
+ {content}
+
+ )
+}
diff --git a/todoblue/src/app/board/[board]/BoardHeader.tsx b/todoblue/src/app/board/[board]/BoardHeader.tsx
index 9c33ea1..4d68c60 100644
--- a/todoblue/src/app/board/[board]/BoardHeader.tsx
+++ b/todoblue/src/app/board/[board]/BoardHeader.tsx
@@ -1,13 +1,15 @@
+import {useManagedStarred} from "@/app/StarContext"
import {useRouter} from "next/navigation"
import {ReactNode, useCallback} from "react"
import style from "./BoardHeader.module.css"
import {useManagedBoard} from "@/app/board/[board]/BoardManager"
-import {faArrowDownWideShort, faHouse, faPencil, faObjectGroup, faTableColumns} from "@fortawesome/free-solid-svg-icons"
+import {faArrowDownWideShort, faHouse, faPencil, faObjectGroup, faTableColumns, faStar as faStarSolid} from "@fortawesome/free-solid-svg-icons"
+import {faStar as faStarRegular} from "@fortawesome/free-regular-svg-icons"
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
import cn from "classnames"
-export function BoardHeader({className}: {className?: string}) {
+export function BoardHeader({className}: {boardName: string, className?: string}) {
const {isEditingTitle} = useManagedBoard();
return (
@@ -17,6 +19,7 @@ export function BoardHeader({className}: {className?: string}) {
+
@@ -93,6 +96,20 @@ function HomeButton() {
)
}
+function StarButton() {
+ const {name} = useManagedBoard()
+ const {starred, addStarred, removeStarred} = useManagedStarred()
+ const isStarred = starred.indexOf(name) >= 0
+
+ const toggleStarred = useCallback(() => isStarred ? removeStarred(name) : addStarred(name), [name, isStarred, addStarred, removeStarred])
+
+ return (
+
+ )
+}
+
function EditTitleButton() {
const {webSocketState, toggleEditingTitle} = useManagedBoard()
@@ -116,7 +133,7 @@ function RightButtonsArea({children}: {children: ReactNode}) {
}
function ToggleSingleColumnButton() {
- const {webSocketState, isSingleColumn, setSingleColumn} = useManagedBoard()
+ const {webSocketState, setSingleColumn} = useManagedBoard()
if(webSocketState != WebSocket.OPEN) {
return null;
diff --git a/todoblue/src/app/board/[board]/useBoard.tsx b/todoblue/src/app/board/[board]/useBoard.tsx
index a16a173..d379abc 100644
--- a/todoblue/src/app/board/[board]/useBoard.tsx
+++ b/todoblue/src/app/board/[board]/useBoard.tsx
@@ -11,6 +11,7 @@ import {useCycleState} from "@/app/useCycleState"
import {Dispatch, SetStateAction, useState} from "react"
export interface UseBoardReturns {
+ name: string,
title: string,
tasksById: {[id: string]: Task},
taskGroups: TaskGroup[],
@@ -50,6 +51,7 @@ export function useBoard(name: string): UseBoardReturns {
const [isSingleColumn, setSingleColumn] = useState(false)
return {
+ name,
title,
tasksById,
taskGroups,
diff --git a/todoblue/src/app/layout.tsx b/todoblue/src/app/layout.tsx
index 8ef2cbe..7c1a6c6 100644
--- a/todoblue/src/app/layout.tsx
+++ b/todoblue/src/app/layout.tsx
@@ -2,6 +2,7 @@
import "./layout.css";
import {AppBody} from "@/app/AppBody"
+import {StarredManager} from "@/app/StarContext"
import type {Metadata as NextMetadata} from "next"
import {default as React, ReactNode} from "react"
@@ -24,7 +25,9 @@ export default function layout({children}: { children: ReactNode }) {
return (
- {children}
+
+ {children}
+
)
diff --git a/todoblue/yarn.lock b/todoblue/yarn.lock
index a649c92..34d5ffe 100644
--- a/todoblue/yarn.lock
+++ b/todoblue/yarn.lock
@@ -302,6 +302,11 @@ typescript@5.1.6:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274"
integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==
+use-local-storage@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/use-local-storage/-/use-local-storage-3.0.0.tgz#ecf90952374150f0c65baf027eaaf2062a4c20c6"
+ integrity sha512-wlPNnBCG3ULIJMr5A+dvWqLiPWCfsN1Kwijq+sAhT5yV4ex0u6XmZuNwP+RerIOfzBuz1pwSZuzhZMiluGQHfQ==
+
watchpack@2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d"