mirror of
https://github.com/Steffo99/todocolors.git
synced 2024-11-22 08:14:18 +00:00
Add starring mechanism
This commit is contained in:
parent
d750d7949b
commit
567818e95e
8 changed files with 149 additions and 5 deletions
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
|||
<CreatePublicBoardPanel/>
|
||||
<CreatePrivateBoardPanel/>
|
||||
</div>
|
||||
<div className={"chapter-1"}>
|
||||
<h2>
|
||||
Usa un tabellone già esistente
|
||||
</h2>
|
||||
<StarredBoardsPanel/>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
|
|
57
todoblue/src/app/StarContext.tsx
Normal file
57
todoblue/src/app/StarContext.tsx
Normal file
|
@ -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<SetStateAction<string[] | undefined>>
|
||||
addStarred: (key: string) => void,
|
||||
removeStarred: (key: string) => void,
|
||||
}
|
||||
|
||||
const StarContext = createContext<StarContextData | null>(null)
|
||||
|
||||
export function StarredManager({children}: {children: ReactNode}) {
|
||||
const [starred, setStarred] = useLocalStorage<string[]>("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 (
|
||||
<StarContext.Provider value={{starred, setStarred, addStarred, removeStarred}}>
|
||||
{children}
|
||||
</StarContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function useManagedStarred(): StarContextData {
|
||||
const context = useContext(StarContext)
|
||||
|
||||
if(context === null) {
|
||||
throw new Error("useStarContext used outside a StarContext.")
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
52
todoblue/src/app/StarredBoardsPanel.tsx
Normal file
52
todoblue/src/app/StarredBoardsPanel.tsx
Normal file
|
@ -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<true | null>(null);
|
||||
const {starred} = useManagedStarred()
|
||||
|
||||
useEffect(() => setIsClient(true), [])
|
||||
|
||||
let content;
|
||||
if(!isClient) {
|
||||
content = <>
|
||||
<p>
|
||||
Sto recuperando i dati salvati sul tuo browser...
|
||||
</p>
|
||||
</>
|
||||
}
|
||||
else {
|
||||
content = <>
|
||||
<p>
|
||||
Puoi stellare un tabellone cliccando sulla stellina una volta che ci sei dentro.
|
||||
</p>
|
||||
{starred.length > 0 ?
|
||||
<ul>
|
||||
{starred.map(s => <li key={s}><Link href={`/board/${s}`}><code>{s}</code></Link></li>)}
|
||||
</ul>
|
||||
:
|
||||
<p className={"fade"}>
|
||||
Non hai ancora stellato nessun tabellone.
|
||||
</p>
|
||||
}
|
||||
</>
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cn({
|
||||
"panel": true,
|
||||
"box": true,
|
||||
"fade": !isClient,
|
||||
})}>
|
||||
<h3>
|
||||
Tabelloni stellati
|
||||
</h3>
|
||||
{content}
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -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}) {
|
|||
</TitleArea>
|
||||
<LeftButtonsArea>
|
||||
<HomeButton/>
|
||||
<StarButton/>
|
||||
<EditTitleButton/>
|
||||
</LeftButtonsArea>
|
||||
<RightButtonsArea>
|
||||
|
@ -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 (
|
||||
<button title={"Stella tabellone"} onClick={toggleStarred}>
|
||||
<FontAwesomeIcon icon={isStarred ? faStarSolid : faStarRegular}/>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -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<boolean>(false)
|
||||
|
||||
return {
|
||||
name,
|
||||
title,
|
||||
tasksById,
|
||||
taskGroups,
|
||||
|
|
|
@ -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 (
|
||||
<html lang="en">
|
||||
<AppBody>
|
||||
<StarredManager>
|
||||
{children}
|
||||
</StarredManager>
|
||||
</AppBody>
|
||||
</html>
|
||||
)
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in a new issue