mirror of
https://github.com/Steffo99/todocolors.git
synced 2024-11-22 16:24:19 +00:00
Fixes and tweaks here and there
This commit is contained in:
parent
34b20c92ce
commit
feb1215a89
13 changed files with 158 additions and 64 deletions
|
@ -8,8 +8,9 @@
|
||||||
<arguments value="--port=8081" />
|
<arguments value="--port=8081" />
|
||||||
<node-interpreter value="project" />
|
<node-interpreter value="project" />
|
||||||
<envs>
|
<envs>
|
||||||
<env name="NEXT_PUBLIC_API_BASE_URL" value="ws://192.168.1.135:8080" />
|
<env name="TODOBLUE_SITE_NAME" value="Tododev" />
|
||||||
<env name="NEXT_PUBLIC_SITE_NAME" value="Tododev" />
|
<env name="TODORED_BASE_URL" value="ws://192.168.1.135:8080" />
|
||||||
|
<env name="TODOBLUE_SITE_DESCRIPTION" value="Development version of Todoblue" />
|
||||||
</envs>
|
</envs>
|
||||||
<method v="2" />
|
<method v="2" />
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use client"
|
"use client";
|
||||||
|
|
||||||
import {useBoardCreator} from "@/app/useBoardCreator"
|
import {useBoardCreator} from "@/app/useBoardCreator"
|
||||||
import {useLowerKebabState} from "@/app/useKebabState"
|
import {useLowerKebabState} from "@/app/useKebabState"
|
||||||
|
|
21
todoblue/src/app/RootFooter.tsx
Normal file
21
todoblue/src/app/RootFooter.tsx
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import style from "@/app/page.module.css"
|
||||||
|
import {useServersideConfiguration} from "@/app/ServersideConfigurationManager"
|
||||||
|
import {default as React} from "react"
|
||||||
|
|
||||||
|
|
||||||
|
export function RootFooter() {
|
||||||
|
const {baseURL} = useServersideConfiguration()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<footer className={style.pageFooter}>
|
||||||
|
<p>
|
||||||
|
© <a href="https://steffo.eu">Stefano Pigozzi</a> -
|
||||||
|
<a href="https://www.gnu.org/licenses/agpl-3.0.en.html">AGPL 3.0</a> -
|
||||||
|
<a href="https://github.com/Steffo99/todocolors">GitHub</a> -
|
||||||
|
Using {baseURL}
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
|
)
|
||||||
|
}
|
18
todoblue/src/app/RootHeader.tsx
Normal file
18
todoblue/src/app/RootHeader.tsx
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import style from "@/app/page.module.css"
|
||||||
|
import {useServersideConfiguration} from "@/app/ServersideConfigurationManager"
|
||||||
|
import {default as React} from "react"
|
||||||
|
|
||||||
|
|
||||||
|
export function RootHeader() {
|
||||||
|
const {siteName} = useServersideConfiguration()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<header className={style.pageHeader}>
|
||||||
|
<h1>
|
||||||
|
{siteName}
|
||||||
|
</h1>
|
||||||
|
</header>
|
||||||
|
)
|
||||||
|
}
|
19
todoblue/src/app/RootMain.tsx
Normal file
19
todoblue/src/app/RootMain.tsx
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import {CreatePrivateBoardPanel} from "@/app/CreatePrivateBoardPanel"
|
||||||
|
import {CreatePublicBoardPanel} from "@/app/CreatePublicBoardPanel"
|
||||||
|
import style from "@/app/page.module.css"
|
||||||
|
import {default as React} from "react"
|
||||||
|
|
||||||
|
|
||||||
|
export function RootMain() {
|
||||||
|
return (
|
||||||
|
<main className={style.pageMain}>
|
||||||
|
<div className={"chapter-2"}>
|
||||||
|
<h2>
|
||||||
|
Crea un nuovo tabellone
|
||||||
|
</h2>
|
||||||
|
<CreatePublicBoardPanel/>
|
||||||
|
<CreatePrivateBoardPanel/>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
)
|
||||||
|
}
|
47
todoblue/src/app/ServersideConfigurationManager.tsx
Normal file
47
todoblue/src/app/ServersideConfigurationManager.tsx
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
"use client";
|
||||||
|
import {createContext, ReactNode, useContext} from "react"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **Object** containing the site options configurable via runtime environment variables.
|
||||||
|
*/
|
||||||
|
export interface ServersideConfiguration {
|
||||||
|
siteName: string,
|
||||||
|
baseURL: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **Context** where the {@link ServersideConfiguration} is stored in.
|
||||||
|
*/
|
||||||
|
export const ServersideConfigurationContext = createContext<ServersideConfiguration | null>(null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **Component** acting as a provider for the {@link ServersideConfigurationContext} for its children.
|
||||||
|
*
|
||||||
|
* Required to execute only on the client.
|
||||||
|
*
|
||||||
|
* @param value The {@link ServersideConfiguration} to provide.
|
||||||
|
* @param children The {@link ReactNode}s to provide the {@link ServersideConfiguration} to.
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
export function ServersideConfigurationManager({value, children}: {value: ServersideConfiguration, children: ReactNode}) {
|
||||||
|
return (
|
||||||
|
<ServersideConfigurationContext.Provider value={value}>
|
||||||
|
{children}
|
||||||
|
</ServersideConfigurationContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **Hook** to access the globally provided {@link ServersideConfiguration} from children components.
|
||||||
|
*/
|
||||||
|
export function useServersideConfiguration(): ServersideConfiguration {
|
||||||
|
const context = useContext(ServersideConfigurationContext);
|
||||||
|
|
||||||
|
if(context === null) {
|
||||||
|
console.error("[useServersideConfiguration] Was used outside of a ServersideConfigurationContext!")
|
||||||
|
throw Error("Used useServersideConfiguration outside of a ServersideConfigurationContext.")
|
||||||
|
}
|
||||||
|
|
||||||
|
return context
|
||||||
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
import "server-only"
|
|
||||||
|
|
||||||
export function SiteName() {
|
|
||||||
return <>
|
|
||||||
{process.env["NEXT_PUBLIC_SITE_NAME"] ?? "Todoblue"}
|
|
||||||
</>
|
|
||||||
}
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
import {TaskIconEl} from "@/app/board/[board]/TaskIconEl"
|
import {TaskIconEl} from "@/app/board/[board]/TaskIconEl"
|
||||||
import {TaskWithId} from "@/app/board/[board]/Types"
|
import {TaskWithId} from "@/app/board/[board]/Types"
|
||||||
import {useManagedBoard} from "@/app/board/[board]/BoardManager"
|
import {useManagedBoard} from "@/app/board/[board]/BoardManager"
|
||||||
|
|
|
@ -6,7 +6,6 @@ import {BoardHeader} from "@/app/board/[board]/BoardHeader"
|
||||||
import {BoardTaskEditor} from "@/app/board/[board]/BoardTaskEditor"
|
import {BoardTaskEditor} from "@/app/board/[board]/BoardTaskEditor"
|
||||||
import style from "./page.module.css"
|
import style from "./page.module.css"
|
||||||
|
|
||||||
|
|
||||||
export default function Page({params: {board}}: {params: {board: string}}) {
|
export default function Page({params: {board}}: {params: {board: string}}) {
|
||||||
return (
|
return (
|
||||||
<BoardManager name={board}>
|
<BoardManager name={board}>
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
|
import {useServersideConfiguration} from "@/app/ServersideConfigurationManager"
|
||||||
import {useMemo} from "react"
|
import {useMemo} from "react"
|
||||||
|
|
||||||
|
|
||||||
export function useBoardWebSocketURL(name: string) {
|
export function useBoardWebSocketURL(name: string) {
|
||||||
const webSocketURL = useMemo(() => `${process.env.NEXT_PUBLIC_API_BASE_URL}/board/${name}/ws`, [name]);
|
const {baseURL} = useServersideConfiguration()
|
||||||
|
|
||||||
|
const webSocketURL = useMemo(() => `${baseURL}/board/${name}/ws`, [name]);
|
||||||
return {webSocketURL}
|
return {webSocketURL}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,25 +2,32 @@
|
||||||
|
|
||||||
import "./layout.css";
|
import "./layout.css";
|
||||||
import {AppBody} from "@/app/AppBody"
|
import {AppBody} from "@/app/AppBody"
|
||||||
|
import {ServersideConfigurationManager} from "@/app/ServersideConfigurationManager"
|
||||||
import { config } from '@fortawesome/fontawesome-svg-core';
|
import {useServersideConfigurationEnvvars} from "@/app/useServersideConfigurationEnvvars"
|
||||||
config.autoAddCss = false; /* eslint-disable import/first */
|
|
||||||
|
|
||||||
import type {Metadata as NextMetadata} from "next"
|
import type {Metadata as NextMetadata} from "next"
|
||||||
import {default as React, ReactNode} from "react"
|
import {default as React, ReactNode} from "react"
|
||||||
|
|
||||||
|
import { config } from '@fortawesome/fontawesome-svg-core';
|
||||||
|
config.autoAddCss = false;
|
||||||
|
|
||||||
|
|
||||||
export const metadata: NextMetadata = {
|
export const metadata: NextMetadata = {
|
||||||
title: "Todoblue",
|
applicationName: process.env["TODOBLUE_SITE_NAME"] ?? "Todoblue",
|
||||||
description: "Self-hostable todo app",
|
title: "Home",
|
||||||
|
description: process.env["TODOBLUE_SITE_DESCRIPTION"] ?? "Self-hosted multiplayer todo app",
|
||||||
|
viewport: {userScalable: false}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function RootLayout({children}: { children: ReactNode }) {
|
export default function layout({children}: { children: ReactNode }) {
|
||||||
|
const serversideConfiguration = useServersideConfigurationEnvvars()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
<ServersideConfigurationManager value={serversideConfiguration}>
|
||||||
<AppBody>
|
<AppBody>
|
||||||
{children}
|
{children}
|
||||||
</AppBody>
|
</AppBody>
|
||||||
|
</ServersideConfigurationManager>
|
||||||
</html>
|
</html>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,50 +1,17 @@
|
||||||
import {CreatePrivateBoardPanel} from "@/app/CreatePrivateBoardPanel"
|
import {RootFooter} from "@/app/RootFooter"
|
||||||
import {CreatePublicBoardPanel} from "@/app/CreatePublicBoardPanel"
|
import {RootHeader} from "@/app/RootHeader"
|
||||||
import {SiteName} from "@/app/SiteName"
|
import {RootMain} from "@/app/RootMain"
|
||||||
import {default as React} from "react";
|
import {default as React} from "react";
|
||||||
import style from "./page.module.css"
|
import style from "./page.module.css"
|
||||||
|
|
||||||
|
|
||||||
export default function Page() {
|
export default function page() {
|
||||||
return <div className={style.pageRoot}>
|
return (
|
||||||
<PageHeader/>
|
<div className={style.pageRoot}>
|
||||||
<PageMain/>
|
<RootHeader/>
|
||||||
<PageFooter/>
|
<RootMain/>
|
||||||
|
<RootFooter/>
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
|
|
||||||
function PageHeader() {
|
|
||||||
return (
|
|
||||||
<header className={style.pageHeader}>
|
|
||||||
<h1>
|
|
||||||
<SiteName/>
|
|
||||||
</h1>
|
|
||||||
</header>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function PageMain() {
|
|
||||||
return (
|
|
||||||
<main className={style.pageMain}>
|
|
||||||
<div className={"chapter-2"}>
|
|
||||||
<h2>
|
|
||||||
Crea un nuovo tabellone
|
|
||||||
</h2>
|
|
||||||
<CreatePublicBoardPanel/>
|
|
||||||
<CreatePrivateBoardPanel/>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function PageFooter() {
|
|
||||||
return (
|
|
||||||
<footer className={style.pageFooter}>
|
|
||||||
<p>
|
|
||||||
© <a href="https://steffo.eu">Stefano Pigozzi</a> -
|
|
||||||
<a href="https://www.gnu.org/licenses/agpl-3.0.en.html">AGPL 3.0</a> -
|
|
||||||
<a href="https://github.com/Steffo99/todocolors">GitHub</a>
|
|
||||||
</p>
|
|
||||||
</footer>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
17
todoblue/src/app/useServersideConfigurationEnvvars.ts
Normal file
17
todoblue/src/app/useServersideConfigurationEnvvars.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import "server-only";
|
||||||
|
import {ServersideConfiguration} from "@/app/ServersideConfigurationManager"
|
||||||
|
|
||||||
|
|
||||||
|
export function useServersideConfigurationEnvvars(): ServersideConfiguration {
|
||||||
|
const siteName = process.env["TODOBLUE_SITE_NAME"]
|
||||||
|
const baseURL = process.env["TODORED_BASE_URL"]
|
||||||
|
|
||||||
|
if(!siteName) {
|
||||||
|
throw Error("TODOBLUE_SITE_NAME is not set.")
|
||||||
|
}
|
||||||
|
if(!baseURL) {
|
||||||
|
throw Error("TODORED_BASE_URL is not set.")
|
||||||
|
}
|
||||||
|
|
||||||
|
return {siteName, baseURL}
|
||||||
|
}
|
Loading…
Reference in a new issue