set basic layout, error boundary, add QR code for 2FA
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
#root {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.box-shadow {
|
||||
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
|
||||
}
|
||||
@@ -3,6 +3,8 @@ import './App.css';
|
||||
import CreateCharacter from "./first-edition/pages/CreateCharacter";
|
||||
import { createBrowserRouter, RouterProvider } from "react-router-dom";
|
||||
import {Faro} from "@grafana/faro-web-sdk";
|
||||
import CharacterList from "./first-edition/pages/CharacterList";
|
||||
import ErrorBoundary from "./first-edition/pages/ErrorBoundary";
|
||||
|
||||
function App(props: {faro?: Faro}) {
|
||||
const router = createBrowserRouter([
|
||||
@@ -10,6 +12,12 @@ function App(props: {faro?: Faro}) {
|
||||
path: "/",
|
||||
element: <CreateCharacter faro={props.faro} />,
|
||||
},
|
||||
{
|
||||
path: "/karaktereim",
|
||||
element: <CharacterList faro={props.faro} />,
|
||||
loader: () => fetch(`/Character`),
|
||||
ErrorBoundary: ErrorBoundary
|
||||
},
|
||||
{
|
||||
path: "/:id",
|
||||
element: <CreateCharacter faro={props.faro} />,
|
||||
@@ -18,9 +26,44 @@ function App(props: {faro?: Faro}) {
|
||||
]);
|
||||
|
||||
return (
|
||||
<div className='container'>
|
||||
<RouterProvider router={router} />
|
||||
</div>
|
||||
<>
|
||||
<header>
|
||||
<nav
|
||||
className="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
|
||||
<div className="container ps-4 pe-4">
|
||||
<a className="navbar-brand" href="/">Kemkas</a>
|
||||
<button className="navbar-toggler" type="button" data-bs-toggle="collapse"
|
||||
data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
|
||||
aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span className="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div className="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
|
||||
|
||||
|
||||
<ul className="navbar-nav">
|
||||
<li className="nav-item">
|
||||
<a className="nav-link text-dark" href="/Identity/Account/Register">Register</a>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<a className="nav-link text-dark" href="/Identity/Account/Login">Login</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<div className='container'>
|
||||
<RouterProvider router={router}/>
|
||||
</div>
|
||||
<footer>
|
||||
<div className="text-center p-4" style={{backgroundColor: "rgba(0, 0, 0, 0.05)"}}>
|
||||
A Kard és Mágiát Lux Gábor alkotta. A szerzői jogok őt illetik. Ez az oldal egy "rajongói
|
||||
hozzájárulás", célja a Kard és Mágia népszerűsítése. Ha többet akarsz tudni a Kard és Mágiáról
|
||||
látogass el a <a href="https://fomalhaut.lfg.hu/">hivatalos honlapjára</a>. A Kard és Mágia az Open
|
||||
Gaming Licence 1.0a alatt lett kiadva, melynek szövege <a href="ogl.html">itt található</a>
|
||||
</div>
|
||||
</footer>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import * as React from "react";
|
||||
import {Osztaly, OsztalyLabel} from "../domain-models/osztaly";
|
||||
import {Faj, FajLabel} from "../domain-models/faj";
|
||||
|
||||
export interface CharacterListItemDto {
|
||||
id: string,
|
||||
name: string,
|
||||
szint: number,
|
||||
faj: Faj,
|
||||
osztaly: Osztaly,
|
||||
}
|
||||
|
||||
function CharacterListItem(props: {
|
||||
character: CharacterListItemDto,
|
||||
}) {
|
||||
const {character:c} = props
|
||||
return <>
|
||||
<td><a href={`/${c.id}`}>{c.name}</a></td>
|
||||
<td>{c.szint}. szintű</td>
|
||||
<td>{FajLabel(c.faj)}</td>
|
||||
<td>{OsztalyLabel(c.osztaly)}</td>
|
||||
</>
|
||||
}
|
||||
|
||||
export default CharacterListItem;
|
||||
@@ -0,0 +1,37 @@
|
||||
import * as React from "react";
|
||||
import {useLoaderData} from "react-router-dom";
|
||||
import CharacterListItem, {CharacterListItemDto} from "../components/CharacterListItem";
|
||||
import {Faro} from "@grafana/faro-web-sdk";
|
||||
|
||||
function CharacterList(props: {faro?: Faro}) {
|
||||
const {faro} = props
|
||||
const characters = useLoaderData() as CharacterListItemDto[];
|
||||
|
||||
return <div className="container">
|
||||
<div className="container-fluid p-5 bg-black text-white text-center">
|
||||
<h1>Karakterek</h1>
|
||||
</div>
|
||||
<div className="d-grid gap-2 m-5">
|
||||
<a className="btn btn-dark btn-lg" href="/" type="button">Új karakter létrehozása</a>
|
||||
</div>
|
||||
<table className="table mt-3">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Név</th>
|
||||
<th scope="col">Szint</th>
|
||||
<th scope="col">Faj</th>
|
||||
<th scope="col">Osztály</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{characters.map(c => (
|
||||
<tr>
|
||||
<CharacterListItem character={c} key={c.id}/>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
|
||||
export default CharacterList;
|
||||
@@ -59,7 +59,7 @@ function CreateCharacterPage(props: {
|
||||
return (
|
||||
<div>
|
||||
<div className='container-fluid p-5 bg-black text-white text-center'>
|
||||
<h1>Karakter létrehozása</h1>
|
||||
<h1>Karakter {initialKarakterInputs ? "szerkesztése*" : "létrehozása"}</h1>
|
||||
</div>
|
||||
<div className='p-3'>
|
||||
<form onSubmit={async (event) => event.preventDefault()}>
|
||||
@@ -179,7 +179,8 @@ function CreateCharacterPage(props: {
|
||||
<button className='btn btn-danger btn-lg' type='button' onClick={async () => {
|
||||
faro?.api.pushEvent('public_character_stored', {
|
||||
osztaly: karakter.osztaly,
|
||||
szint: karakter.szint.toString()
|
||||
szint: karakter.szint.toString(),
|
||||
faj: karakter.faj.toString(),
|
||||
})
|
||||
let newId = await StoreNewCharacter(karakter)
|
||||
const win = window.open(`/${newId}`, '_blank');
|
||||
@@ -196,7 +197,8 @@ function CreateCharacterPage(props: {
|
||||
<button className='btn btn-danger btn-lg' type='button' onClick={async () => {
|
||||
faro?.api.pushEvent('character_created', {
|
||||
osztaly: karakter.osztaly,
|
||||
szint: karakter.szint.toString()
|
||||
szint: karakter.szint.toString(),
|
||||
faj: karakter.faj.toString(),
|
||||
})
|
||||
await CreatePDF(KarakterInputToPdfView(karakter))
|
||||
}}>PDF
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import * as React from "react";
|
||||
|
||||
function ErrorBoundary(props: {}) {
|
||||
|
||||
return <div>
|
||||
<div className="container-fluid p-5 bg-danger text-white text-center">
|
||||
<h1>Valami hiba történt :(</h1>
|
||||
</div>
|
||||
<div className="p-5 text-center">
|
||||
<p>Töltsd újra az oldalt, és ha az sem segít lépj kapcsolatba a fejlesztővel a <a href="mailto:developer@kemkas.hu">developer@kemkas.hu</a> email címen!</p>
|
||||
<p>Kérlek vedd figyelembe, hogy ez egy hobby projekt limitált erőforrásokkal.</p>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
export default ErrorBoundary;
|
||||
@@ -6,8 +6,3 @@ body {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user