added footer with legal and contact
This commit is contained in:
69
client/package-lock.json
generated
69
client/package-lock.json
generated
@@ -17,6 +17,7 @@
|
|||||||
"@nextui-org/divider": "^2.2.5",
|
"@nextui-org/divider": "^2.2.5",
|
||||||
"@nextui-org/form": "^2.1.8",
|
"@nextui-org/form": "^2.1.8",
|
||||||
"@nextui-org/input": "^2.4.8",
|
"@nextui-org/input": "^2.4.8",
|
||||||
|
"@nextui-org/link": "^2.2.7",
|
||||||
"@nextui-org/modal": "^2.2.7",
|
"@nextui-org/modal": "^2.2.7",
|
||||||
"@nextui-org/radio": "^2.3.8",
|
"@nextui-org/radio": "^2.3.8",
|
||||||
"@nextui-org/select": "^2.4.9",
|
"@nextui-org/select": "^2.4.9",
|
||||||
@@ -1248,6 +1249,28 @@
|
|||||||
"react-dom": ">=18 || >=19.0.0-rc.0"
|
"react-dom": ">=18 || >=19.0.0-rc.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@nextui-org/link": {
|
||||||
|
"version": "2.2.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nextui-org/link/-/link-2.2.7.tgz",
|
||||||
|
"integrity": "sha512-SAeBBCUtdaKtHfZgRD6OH0De/+cKUEuThiErSuFW+sNm/y8m3cUhQH8UqVBPu6HwmqVTEjvZzp/4uhG6lcSZjA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@nextui-org/react-utils": "2.1.3",
|
||||||
|
"@nextui-org/shared-icons": "2.1.1",
|
||||||
|
"@nextui-org/shared-utils": "2.1.2",
|
||||||
|
"@nextui-org/use-aria-link": "2.2.5",
|
||||||
|
"@react-aria/focus": "3.19.0",
|
||||||
|
"@react-aria/link": "3.7.7",
|
||||||
|
"@react-aria/utils": "3.26.0",
|
||||||
|
"@react-types/link": "3.5.9"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@nextui-org/system": ">=2.4.0",
|
||||||
|
"@nextui-org/theme": ">=2.4.0",
|
||||||
|
"react": ">=18 || >=19.0.0-rc.0",
|
||||||
|
"react-dom": ">=18 || >=19.0.0-rc.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@nextui-org/listbox": {
|
"node_modules/@nextui-org/listbox": {
|
||||||
"version": "2.3.9",
|
"version": "2.3.9",
|
||||||
"resolved": "https://registry.npmjs.org/@nextui-org/listbox/-/listbox-2.3.9.tgz",
|
"resolved": "https://registry.npmjs.org/@nextui-org/listbox/-/listbox-2.3.9.tgz",
|
||||||
@@ -1651,6 +1674,23 @@
|
|||||||
"react": ">=18 || >=19.0.0-rc.0"
|
"react": ">=18 || >=19.0.0-rc.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@nextui-org/use-aria-link": {
|
||||||
|
"version": "2.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nextui-org/use-aria-link/-/use-aria-link-2.2.5.tgz",
|
||||||
|
"integrity": "sha512-LBWXLecvuET4ZcpoHyyuS3yxvCzXdkmFcODhYwUmC8PiFSEUHkuFMC+fLwdXCP5GOqrv6wTGYHf41wNy1ugX1w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@nextui-org/shared-utils": "2.1.2",
|
||||||
|
"@react-aria/focus": "3.19.0",
|
||||||
|
"@react-aria/interactions": "3.22.5",
|
||||||
|
"@react-aria/utils": "3.26.0",
|
||||||
|
"@react-types/link": "3.5.9",
|
||||||
|
"@react-types/shared": "3.26.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=18 || >=19.0.0-rc.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@nextui-org/use-aria-modal-overlay": {
|
"node_modules/@nextui-org/use-aria-modal-overlay": {
|
||||||
"version": "2.2.3",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@nextui-org/use-aria-modal-overlay/-/use-aria-modal-overlay-2.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/@nextui-org/use-aria-modal-overlay/-/use-aria-modal-overlay-2.2.3.tgz",
|
||||||
@@ -2053,6 +2093,23 @@
|
|||||||
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
|
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@react-aria/link": {
|
||||||
|
"version": "3.7.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-aria/link/-/link-3.7.7.tgz",
|
||||||
|
"integrity": "sha512-eVBRcHKhNSsATYWv5wRnZXRqPVcKAWWakyvfrYePIKpC3s4BaHZyTGYdefk8ZwZdEOuQZBqLMnjW80q1uhtkuA==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@react-aria/focus": "^3.19.0",
|
||||||
|
"@react-aria/interactions": "^3.22.5",
|
||||||
|
"@react-aria/utils": "^3.26.0",
|
||||||
|
"@react-types/link": "^3.5.9",
|
||||||
|
"@react-types/shared": "^3.26.0",
|
||||||
|
"@swc/helpers": "^0.5.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@react-aria/listbox": {
|
"node_modules/@react-aria/listbox": {
|
||||||
"version": "3.13.6",
|
"version": "3.13.6",
|
||||||
"resolved": "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.13.6.tgz",
|
"resolved": "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.13.6.tgz",
|
||||||
@@ -2731,6 +2788,18 @@
|
|||||||
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
|
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@react-types/link": {
|
||||||
|
"version": "3.5.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-types/link/-/link-3.5.9.tgz",
|
||||||
|
"integrity": "sha512-JcKDiDMqrq/5Vpn+BdWQEuXit4KN4HR/EgIi3yKnNbYkLzxBoeQZpQgvTaC7NEQeZnSqkyXQo3/vMUeX/ZNIKw==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@react-types/shared": "^3.26.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@react-types/listbox": {
|
"node_modules/@react-types/listbox": {
|
||||||
"version": "3.5.3",
|
"version": "3.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/@react-types/listbox/-/listbox-3.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/@react-types/listbox/-/listbox-3.5.3.tgz",
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
"@nextui-org/divider": "^2.2.5",
|
"@nextui-org/divider": "^2.2.5",
|
||||||
"@nextui-org/form": "^2.1.8",
|
"@nextui-org/form": "^2.1.8",
|
||||||
"@nextui-org/input": "^2.4.8",
|
"@nextui-org/input": "^2.4.8",
|
||||||
|
"@nextui-org/link": "^2.2.7",
|
||||||
"@nextui-org/modal": "^2.2.7",
|
"@nextui-org/modal": "^2.2.7",
|
||||||
"@nextui-org/radio": "^2.3.8",
|
"@nextui-org/radio": "^2.3.8",
|
||||||
"@nextui-org/select": "^2.4.9",
|
"@nextui-org/select": "^2.4.9",
|
||||||
|
|||||||
32
client/src/app/Footer.tsx
Normal file
32
client/src/app/Footer.tsx
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { Divider } from "@nextui-org/divider";
|
||||||
|
import { Link } from "@nextui-org/link";
|
||||||
|
import { usePathname } from "next/navigation";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export default function Footer({
|
||||||
|
sites,
|
||||||
|
}: {
|
||||||
|
sites: { href: string; text: string }[];
|
||||||
|
}) {
|
||||||
|
const pathname = usePathname();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{sites.map((footer, ii, footerSites) => (
|
||||||
|
<React.Fragment key={ii}>
|
||||||
|
<Link
|
||||||
|
href={footer.href}
|
||||||
|
color={pathname === footer.href ? "danger" : "foreground"}
|
||||||
|
>
|
||||||
|
{footer.text}
|
||||||
|
</Link>
|
||||||
|
{ii != footerSites.length - 1 ? (
|
||||||
|
<Divider orientation="vertical" />
|
||||||
|
) : null}
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
export default function ManageEvents() {}
|
|
||||||
9
client/src/app/datenschutz/page.tsx
Normal file
9
client/src/app/datenschutz/page.tsx
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export default function Datenschutz() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2 className="text-center font-headline text-4xl text-highlight">
|
||||||
|
Datenschutz
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
10
client/src/app/impressum/page.tsx
Normal file
10
client/src/app/impressum/page.tsx
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export default function Impressum() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{" "}
|
||||||
|
<h2 className="text-center font-headline text-4xl text-highlight">
|
||||||
|
Impressum
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
import { NextUIProvider } from "@nextui-org/system";
|
import { NextUIProvider } from "@nextui-org/system";
|
||||||
|
import React from "react";
|
||||||
|
import Footer from "./Footer";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Create Next App",
|
title: "Create Next App",
|
||||||
@@ -12,6 +14,17 @@ export default function RootLayout({
|
|||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}>) {
|
}>) {
|
||||||
|
const footerSites = [
|
||||||
|
{
|
||||||
|
text: "Impressum",
|
||||||
|
href: "/impressum",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Datenschutz",
|
||||||
|
href: "/datenschutz",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html>
|
<html>
|
||||||
<body className="bg-background text-foreground antialiased">
|
<body className="bg-background text-foreground antialiased">
|
||||||
@@ -23,6 +36,9 @@ export default function RootLayout({
|
|||||||
</h1>
|
</h1>
|
||||||
</header>
|
</header>
|
||||||
<main className="flex min-h-full flex-1 flex-col">{children}</main>
|
<main className="flex min-h-full flex-1 flex-col">{children}</main>
|
||||||
|
<footer className="flex h-4 justify-center gap-4">
|
||||||
|
<Footer sites={footerSites} />
|
||||||
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</NextUIProvider>
|
</NextUIProvider>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -1,29 +1,31 @@
|
|||||||
type QueryParams = Record<string, string | { toString(): string }>;
|
type QueryParams = Record<string, string | { toString(): string }>;
|
||||||
|
|
||||||
export type APICallResult<T extends object> = Response & { json: () => Promise<T> };
|
export type APICallResult<T extends object> = Response & {
|
||||||
|
json: () => Promise<T>;
|
||||||
|
};
|
||||||
|
|
||||||
export async function apiCall<K extends object>(
|
export async function apiCall<K extends object>(
|
||||||
method: "GET",
|
method: "GET",
|
||||||
api: string,
|
api: string,
|
||||||
params?: QueryParams
|
params?: QueryParams,
|
||||||
): Promise<APICallResult<K>>;
|
): Promise<APICallResult<K>>;
|
||||||
export async function apiCall<K extends object>(
|
export async function apiCall<K extends object>(
|
||||||
method: "POST" | "PATCH",
|
method: "POST" | "PATCH",
|
||||||
api: string,
|
api: string,
|
||||||
params?: QueryParams,
|
params?: QueryParams,
|
||||||
body?: object
|
body?: object,
|
||||||
): Promise<APICallResult<K>>;
|
): Promise<APICallResult<K>>;
|
||||||
export async function apiCall<K extends object>(
|
export async function apiCall<K extends object>(
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
api: string,
|
api: string,
|
||||||
params?: QueryParams,
|
params?: QueryParams,
|
||||||
body?: object
|
body?: object,
|
||||||
): Promise<APICallResult<K>>;
|
): Promise<APICallResult<K>>;
|
||||||
export async function apiCall<K extends object>(
|
export async function apiCall<K extends object>(
|
||||||
method: "GET" | "POST" | "PATCH" | "DELETE",
|
method: "GET" | "POST" | "PATCH" | "DELETE",
|
||||||
api: string,
|
api: string,
|
||||||
params?: QueryParams,
|
params?: QueryParams,
|
||||||
body?: object
|
body?: object,
|
||||||
): Promise<APICallResult<K>> {
|
): Promise<APICallResult<K>> {
|
||||||
let url = window.origin + "/api/" + api;
|
let url = window.origin + "/api/" + api;
|
||||||
|
|
||||||
@@ -36,8 +38,8 @@ export async function apiCall<K extends object>(
|
|||||||
} else {
|
} else {
|
||||||
return [key, value];
|
return [key, value];
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
url += "?" + urlsearchparams.toString();
|
url += "?" + urlsearchparams.toString();
|
||||||
@@ -45,12 +47,22 @@ export async function apiCall<K extends object>(
|
|||||||
|
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json; charset=UTF-8"
|
"Content-Type": "application/json; charset=UTF-8",
|
||||||
},
|
},
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
method,
|
method,
|
||||||
body: body !== undefined ? JSON.stringify(body) : undefined
|
body: body !== undefined ? JSON.stringify(body) : undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function classNames(classNames: Record<string, boolean>): string {
|
||||||
|
return Object.entries(classNames)
|
||||||
|
.map(([classString, value]) => {
|
||||||
|
if (value) {
|
||||||
|
return classString;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.join(" ");
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user