mirror of
https://github.com/Steffo99/todocolors.git
synced 2024-11-22 00:04:18 +00:00
Various fixes
This commit is contained in:
parent
0c3b44a505
commit
ced9053789
10 changed files with 91 additions and 43 deletions
|
@ -1,8 +1,10 @@
|
|||
{
|
||||
"name": "Todocolors",
|
||||
"short_name": "Todocolors",
|
||||
"short_name": "Todo",
|
||||
"start_url": ".",
|
||||
"scope": "/",
|
||||
"display": "standalone",
|
||||
"theme_color": "#0d193b",
|
||||
"background_color": "#0c193b",
|
||||
"description": "Self-hostable multiplayer todo app",
|
||||
"categories": ["productivity"],
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
.taskEditorContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
|
@ -8,8 +9,6 @@
|
|||
align-items: center;
|
||||
border-style: dashed;
|
||||
|
||||
width: 100%;
|
||||
max-width: 480px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
.titleArea {
|
||||
grid-area: title;
|
||||
height: 72px;
|
||||
}
|
||||
|
||||
.titleDisplay {
|
||||
|
|
|
@ -22,12 +22,12 @@ interface BoardHeaderProps {
|
|||
export function BoardHeader({lang, className, metadataHook, layoutHook: {columningHook, groupingHook, sortingHook}}: BoardHeaderProps) {
|
||||
return (
|
||||
<header className={cn(style.boardHeader, className)}>
|
||||
<BoardHeaderTitle className={style.titleArea} editorHook={metadataHook}/>
|
||||
<div className={cn(style.buttonsArea, style.leftButtonsArea)}>
|
||||
<NavigateHomeButton lang={lang}/>
|
||||
<ToggleStarredButton lang={lang}/>
|
||||
<ToggleEditingButton lang={lang} metadataHook={metadataHook}/>
|
||||
</div>
|
||||
<BoardHeaderTitle className={style.titleArea} editorHook={metadataHook}/>
|
||||
<div className={cn(style.buttonsArea, style.rightButtonsArea)}>
|
||||
<CycleColumningButton lang={lang} value={columningHook.value} next={columningHook.next}/>
|
||||
<CycleGroupingButton lang={lang} next={groupingHook.next}/>
|
||||
|
|
|
@ -18,5 +18,9 @@
|
|||
}
|
||||
|
||||
.taskViewerBack {
|
||||
flex-direction: row-reverse;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.taskViewerDebug {
|
||||
font-size: xx-small;
|
||||
}
|
||||
|
|
|
@ -9,12 +9,23 @@ import {TaskWithId} from "@/app/[lang]/board/[board]/(page)/(view)/(task)/TaskWi
|
|||
import {faTrashArrowUp} from "@fortawesome/free-solid-svg-icons"
|
||||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
|
||||
import cn from "classnames"
|
||||
import {Dispatch, MouseEvent, SetStateAction, useCallback, useState} from "react"
|
||||
import {Dispatch, SyntheticEvent, SetStateAction, useCallback, useState} from "react"
|
||||
|
||||
|
||||
export function TaskViewer({lang, task, setEditorInput}: {lang: string, task: TaskWithId, setEditorInput: Dispatch<SetStateAction<string>>}) {
|
||||
const [isFlipped, setFlipped] = useState<boolean>(false)
|
||||
|
||||
const toggleFlipped = useCallback((e: SyntheticEvent<HTMLElement>) => {
|
||||
if("key" in e && typeof e["key"] === "string") {
|
||||
if(!["Enter", " "].includes(e.key)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
setFlipped(prev => !prev)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn({
|
||||
|
@ -23,17 +34,23 @@ export function TaskViewer({lang, task, setEditorInput}: {lang: string, task: Ta
|
|||
[style.taskViewerFront]: !isFlipped,
|
||||
[style.taskViewerBack]: isFlipped,
|
||||
}, taskClassNames(task[1]))}
|
||||
onClick={() => setFlipped(prev => !prev)}
|
||||
onClick={toggleFlipped}
|
||||
onKeyDownCapture={toggleFlipped}
|
||||
>
|
||||
{isFlipped ? <TaskViewerBack lang={lang} task={task} setEditorInput={setEditorInput}/> : <TaskViewerFront lang={lang} task={task}/>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function TaskViewerFront({lang, task}: {lang: string, task: TaskWithId}) {
|
||||
function TaskViewerFront({task}: {lang: string, task: TaskWithId}) {
|
||||
const {sendRequest} = useBoardConsumer()
|
||||
|
||||
const toggleStatus = useCallback((e: MouseEvent<HTMLDivElement>) => {
|
||||
const toggleStatus = useCallback((e: SyntheticEvent<HTMLDivElement>) => {
|
||||
if("key" in e && typeof e["key"] === "string") {
|
||||
if(!["Enter", " "].includes(e.key)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
let request: ModifyTaskBoardRequest
|
||||
|
@ -52,7 +69,7 @@ function TaskViewerFront({lang, task}: {lang: string, task: TaskWithId}) {
|
|||
}, [task, sendRequest])
|
||||
|
||||
return <>
|
||||
<div className={style.taskIcon} onClick={toggleStatus} tabIndex={0}>
|
||||
<div className={style.taskIcon} onClick={toggleStatus} onKeyDown={toggleStatus} tabIndex={0}>
|
||||
<FontAwesomeIcon
|
||||
size={"lg"}
|
||||
icon={task[1].status === TaskStatus.Complete ? TASK_ICON_TO_FONTAWESOME_SOLID[task[1].icon] : TASK_ICON_TO_FONTAWESOME_REGULAR[task[1].icon]}
|
||||
|
@ -69,7 +86,12 @@ function TaskViewerBack({lang, task, setEditorInput}: {lang: string, task: TaskW
|
|||
const {t} = useClientTranslation(lang, "board")
|
||||
const {sendRequest} = useBoardConsumer()
|
||||
|
||||
const recreateTask = useCallback((e: MouseEvent<HTMLButtonElement>) => {
|
||||
const recreateTask = useCallback((e: SyntheticEvent<HTMLButtonElement>) => {
|
||||
if("key" in e && typeof e["key"] === "string") {
|
||||
if(!["Enter", " "].includes(e.key)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
setEditorInput(taskToString(task[1]))
|
||||
|
@ -78,8 +100,11 @@ function TaskViewerBack({lang, task, setEditorInput}: {lang: string, task: TaskW
|
|||
}, [task, setEditorInput, sendRequest])
|
||||
|
||||
return <>
|
||||
<div className={style.taskButtons}>
|
||||
<button title={t("taskButtonRecreate")} onClick={recreateTask}>
|
||||
<div className={style.taskViewerDebug}>
|
||||
{task[0]}
|
||||
</div>
|
||||
<div className={style.taskViewerButtons}>
|
||||
<button title={t("taskButtonRecreate")} onClick={recreateTask} onKeyDown={recreateTask} tabIndex={0}>
|
||||
<FontAwesomeIcon size={"sm"} icon={faTrashArrowUp}/>
|
||||
</button>
|
||||
</div>
|
||||
|
|
40
todoblue/src/app/[lang]/board/[board]/(page)/BoardPage.tsx
Normal file
40
todoblue/src/app/[lang]/board/[board]/(page)/BoardPage.tsx
Normal file
|
@ -0,0 +1,40 @@
|
|||
"use client";
|
||||
|
||||
import {TaskEditor} from "@/app/[lang]/board/[board]/(page)/(edit)/TaskEditor"
|
||||
import {BoardHeader} from "@/app/[lang]/board/[board]/(page)/(header)/BoardHeader"
|
||||
import {BoardMain} from "@/app/[lang]/board/[board]/(page)/(view)/BoardMain"
|
||||
import {useBoardLayoutEditor} from "@/app/[lang]/board/[board]/(page)/useBoardLayoutEditor"
|
||||
import {useBoardMetadataEditor} from "@/app/[lang]/board/[board]/(page)/useBoardMetadataEditor"
|
||||
import {useTaskEditor} from "@/app/[lang]/board/[board]/(page)/useTaskEditor"
|
||||
import style from "@/app/[lang]/board/[board]/page.module.css"
|
||||
|
||||
|
||||
export function BoardPage({lang}: {lang: string}) {
|
||||
const metadataHook = useBoardMetadataEditor()
|
||||
const layoutHook = useBoardLayoutEditor()
|
||||
const editorHook = useTaskEditor()
|
||||
|
||||
return (
|
||||
<div className={style.pageRoot}>
|
||||
<BoardHeader
|
||||
lang={lang}
|
||||
className={style.pageHeader}
|
||||
metadataHook={metadataHook}
|
||||
layoutHook={layoutHook}
|
||||
/>
|
||||
<BoardMain
|
||||
lang={lang}
|
||||
className={style.pageMain}
|
||||
columning={layoutHook.columningHook.value}
|
||||
grouping={layoutHook.groupingHook.value}
|
||||
sorting={layoutHook.sortingHook.value}
|
||||
setEditorInput={editorHook.setInput}
|
||||
/>
|
||||
<TaskEditor
|
||||
lang={lang}
|
||||
className={style.pageEditor}
|
||||
editorHook={editorHook}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -6,7 +6,8 @@
|
|||
"main"
|
||||
"editor"
|
||||
;
|
||||
grid-template-rows: 72px 1fr 48px;
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: auto 1fr 48px;
|
||||
grid-row-gap: 8px;
|
||||
|
||||
justify-content: stretch;
|
||||
|
@ -30,6 +31,4 @@
|
|||
|
||||
.pageEditor {
|
||||
grid-area: editor;
|
||||
|
||||
min-height: 44px;
|
||||
}
|
||||
|
|
|
@ -1,39 +1,16 @@
|
|||
"use client";
|
||||
import {TaskEditor} from "@/app/[lang]/board/[board]/(page)/(edit)/TaskEditor"
|
||||
import {BoardPage} from "@/app/[lang]/board/[board]/(page)/BoardPage"
|
||||
import {useBoardLayoutEditor} from "@/app/[lang]/board/[board]/(page)/useBoardLayoutEditor"
|
||||
import {useBoardMetadataEditor} from "@/app/[lang]/board/[board]/(page)/useBoardMetadataEditor"
|
||||
import {BoardMain} from "@/app/[lang]/board/[board]/(page)/(view)/BoardMain"
|
||||
import {BoardHeader} from "@/app/[lang]/board/[board]/(page)/(header)/BoardHeader"
|
||||
import {useTaskEditor} from "@/app/[lang]/board/[board]/(page)/useTaskEditor"
|
||||
import {Metadata} from "next"
|
||||
import style from "./page.module.css"
|
||||
|
||||
|
||||
export default function page({params: {lang}}: {params: {lang: string}}) {
|
||||
const metadataHook = useBoardMetadataEditor()
|
||||
const layoutHook = useBoardLayoutEditor()
|
||||
const editorHook = useTaskEditor()
|
||||
|
||||
return (
|
||||
<div className={style.pageRoot}>
|
||||
<BoardHeader
|
||||
lang={lang}
|
||||
className={style.pageHeader}
|
||||
metadataHook={metadataHook}
|
||||
layoutHook={layoutHook}
|
||||
/>
|
||||
<BoardMain
|
||||
lang={lang}
|
||||
className={style.pageMain}
|
||||
columning={layoutHook.columningHook.value}
|
||||
grouping={layoutHook.groupingHook.value}
|
||||
sorting={layoutHook.sortingHook.value}
|
||||
setEditorInput={editorHook.setInput}
|
||||
/>
|
||||
<TaskEditor
|
||||
lang={lang}
|
||||
className={style.pageEditor}
|
||||
editorHook={editorHook}
|
||||
/>
|
||||
</div>
|
||||
<BoardPage lang={lang}/>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -18,7 +18,8 @@ export const metadata: NextMetadata = {
|
|||
creator: "Steffo",
|
||||
robots: "noindex, nofollow",
|
||||
manifest: "manifest.json",
|
||||
icons: "favicon-wbg.ico"
|
||||
icons: "favicon-wbg.ico",
|
||||
themeColor: "#0d193b"
|
||||
}
|
||||
|
||||
export default function layout({children}: { children: ReactNode }) {
|
||||
|
|
Loading…
Reference in a new issue