tabor web

This commit is contained in:
Karel Košnar 2024-01-04 15:51:49 +01:00
parent 3bf72345fc
commit 773d65d95a
19 changed files with 8577 additions and 9 deletions

View file

@ -1,11 +1,12 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Dětský stanový tábor ve Střílkách</title>
</head>
<body> <body>
<div id="root"></div>
<h1>My First Heading</h1> <script type="module" src="/src/main.tsx"></script>
<p>My first paragraph.</p>
</body> </body>
</html> </html>

8222
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

38
package.json Normal file
View file

@ -0,0 +1,38 @@
{
"name": "frontend",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"setup": "node ./contentful/setup.cjs"
},
"dependencies": {
"@contentful/rich-text-react-renderer": "^15.17.0",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@fontsource/roboto": "^5.0.3",
"@mui/material": "^5.13.5",
"contentful": "^10.2.4",
"contentful-import": "^8.5.57",
"dotenv": "^16.1.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.12.1"
},
"devDependencies": {
"@types/react": "^18.0.37",
"@types/react-dom": "^18.0.11",
"@typescript-eslint/eslint-plugin": "^5.59.0",
"@typescript-eslint/parser": "^5.59.0",
"@vitejs/plugin-react": "^4.0.0",
"eslint": "^8.38.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.3.4",
"typescript": "^5.0.2",
"vite": "^4.3.9"
}
}

0
public/.gitkeep Normal file
View file

1
public/_redirects Normal file
View file

@ -0,0 +1 @@
/* /index.html 200

42
src/App.css Normal file
View file

@ -0,0 +1,42 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}
@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}
.card {
padding: 2em;
}
.read-the-docs {
color: #888;
}

89
src/App.tsx Normal file
View file

@ -0,0 +1,89 @@
import "./App.css";
import Page from "./containers/Page/Page";
import { LandingPageSkeleton } from "../types/contentful";
import { Entry, createClient } from "contentful";
import MainNav from "./containers/MainNav/MainNav";
import { useEffect, useState } from "react";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
function App() {
const [contentfuldata, setData] =
useState<Entry<LandingPageSkeleton, undefined, string>[]>();
const client = createClient({
space: import.meta.env.VITE_CONTENTFUL_SPACE_ID,
accessToken: import.meta.env.VITE_CONTENTFUL_DELIVERY_TOKEN,
});
useEffect(() => {
const ass = async () => {
const response = await client.getEntries<LandingPageSkeleton>({
content_type: "landing-page",
});
console.log(response.items);
return setData(response.items);
};
ass();
}, []);
if (contentfuldata === null || contentfuldata === undefined) {
return <></>;
}
const current = contentfuldata.filter(
(n) => n.sys.id !== "7IShhDv8NE55WfsQf4RKuW"
)[0];
const prihlaska = contentfuldata.filter(
(n) => n.sys.id === "7IShhDv8NE55WfsQf4RKuW"
)[0];
const router = createBrowserRouter(
[
{
path: "/",
element: (
<Page title={current.fields.title} content={current.fields.content} />
),
},
{
path: "/prihlaska",
element: (
<Page
title={prihlaska.fields.title}
content={prihlaska.fields.content}
/>
),
},
{
element: <h1>Stránka nenalezena.</h1>,
path: "*",
},
],
{
basename: import.meta.env.VITE_BASENAME,
}
);
return (
<>
<MainNav />
<div
style={{
backgroundColor: "#ffe6b8",
padding: "1rem",
marginBlockStart: "2rem",
}}
>
Naše webové stránky jsou v rekonstrukci, děkujeme za trpělivost. V
případě dotazů prosím kontaktuje hlavního vedoucího <b>Karla Košnara</b>{" "}
na emailové adrese <b>karel.kosnar (zavináč) gmail.com</b> nebo na
telefonu <b>608 906 987</b>.
</div>
<RouterProvider router={router} />
</>
);
}
export default App;

View file

@ -0,0 +1,4 @@
.link {
padding: 1rem;
display: inline-block;
}

View file

@ -0,0 +1,19 @@
import styles from "./LinkButton.module.css";
interface LinkButtonInterface {
text: string;
link: string;
type?: string;
}
const LinkButton = ({ text, link, type }: LinkButtonInterface) => {
return (
<div className={styles.link}>
<a className={type} href={link}>
{text}
</a>
</div>
);
};
export default LinkButton;

View file

@ -0,0 +1,5 @@
.title {
font-size: 1.5rem;
font-weight: bold;
color: darkgreen;
}

View file

@ -0,0 +1,19 @@
import styles from "./MainNav.module.css";
const MainNav = () => {
return (
<>
<div className={styles.title}>Dětský stanový tábor ve Střílkách</div>
<nav>
{/* <LinkButton text="Přihláška" link="" />
<LinkButton text="Filozofie" link="" />
<LinkButton text="Tým" link="" />
<LinkButton text="Minulé tábory" link="" />
<LinkButton text="Kontakt" link="" /> */}
</nav>
</>
);
};
export default MainNav;

View file

@ -0,0 +1,18 @@
.poster {
max-width: min(100%, 30rem);
margin: 0 auto;
}
.content {
max-width: 50rem;
margin-left: auto;
margin-right: auto;
}
.content * {
text-align: left;
}
.content image {
text-align: center;
}

View file

@ -0,0 +1,41 @@
import styles from "./Page.module.css";
import { documentToReactComponents } from "@contentful/rich-text-react-renderer";
import { BLOCKS } from "@contentful/rich-text-types";
interface InvitationBlockInterface {
title: string;
content: any;
}
const InvitationBlock = ({ title, content }: InvitationBlockInterface) => {
return (
<>
<div>
<h1>{title}</h1>
<div className={styles.content}>
{documentToReactComponents(content, {
renderText: (text) => {
return text.split("\n").reduce((lines, textSegment, index) => {
return [...lines, index > 0 && <br key={index} />, textSegment];
}, new Array()); // eslint-disable-line @typescript-eslint/no-array-constructor
},
renderNode: {
[BLOCKS.EMBEDDED_ASSET]: (node) => {
return (
<img
src={`https://${node.data.target.fields.file.url}`}
alt={node.data.target.fields.description}
className={styles.poster}
/>
);
},
},
})}
</div>
</div>
</>
);
};
export default InvitationBlock;

17
src/main.tsx Normal file
View file

@ -0,0 +1,17 @@
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";
import "@fontsource/roboto/300.css";
import "@fontsource/roboto/400.css";
import "@fontsource/roboto/500.css";
import "@fontsource/roboto/700.css";
import CssBaseline from "@mui/material/CssBaseline";
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<CssBaseline />
<App />
</React.StrictMode>
);

1
src/vite-env.d.ts vendored Normal file
View file

@ -0,0 +1 @@
/// <reference types="vite/client" />

25
tsconfig.json Normal file
View file

@ -0,0 +1,25 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}

10
tsconfig.node.json Normal file
View file

@ -0,0 +1,10 @@
{
"compilerOptions": {
"composite": true,
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}

9
types/contentful.tsx Normal file
View file

@ -0,0 +1,9 @@
import contentful from "contentful";
export type LandingPageSkeleton = {
contentTypeId: "landing-page";
fields: {
title: contentful.EntryFieldTypes.Symbol;
content: contentful.EntryFieldTypes.RichText;
};
};

7
vite.config.ts Normal file
View file

@ -0,0 +1,7 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
})