diaREact/resources/js/components/pages/App.tsx

228 lines
7.1 KiB
TypeScript

import PageForm from "./Form";
import Pages from "./List";
import Prompt from "./Prompt";
import * as React from 'react';
import {Alert, AlertTitle, Button, Divider} from "@mui/material";
import {EncryptStorage} from "storage-encryption";
import {
Switch,
Route,
Link,
Redirect,
withRouter,
useHistory
} from "react-router-dom";
import {IList} from "../../interfaces/IList";
import {isAllLoadedLocally} from "../../utils";
import CalendarHeatmap from "../calendar/CalendarHeatmap";
import {CalendarHeatmapValuesProp} from "../calendar/CalendarHeatmapValuesProp";
const app = document.getElementById('app');
const word = "shikiryu"; // FIXME should be in db and ≠ between users
const sessionPassphrase = sessionStorage.getItem("key") as string;
let pages: IList[] = [];
let getPageContentUrl,
postUrl,
settings,
removeUrl,
checkword,
startDate,
csrf = "";
if (app) {
getPageContentUrl = "" + app.getAttribute('data-url');
pages = JSON.parse("" + app.getAttribute('data-list')) as IList[];
postUrl = "" + app.getAttribute('data-post');
startDate = "" + app.getAttribute('data-start');
settings = JSON.parse("" + app.getAttribute('data-settings'));
removeUrl = "" + app.getAttribute('data-remove');
csrf = "" + app.getAttribute('data-csrf');
checkword = "" + app.getAttribute('data-checkword');
}
function App() {
const [listPages, setListPages] = React.useState<IList[]>(pages);
const [passphrase, setPassphrase] = React.useState<string>(sessionPassphrase);
const history = useHistory();
const [user, setUser] = React.useState(checkPassphrase());
const [error, isError] = React.useState(!checkPassphrase());
const [allLoaded, setAllLoaded] = React.useState<boolean>(isAllLoadedLocally(pages));
const loadPages = React.useRef(() => {return ;});
const signin = cb => {
const isAuthenticated = checkPassphrase();
setUser(isAuthenticated);
if (isAuthenticated) {
isError(false);
cb();
} else {
isError(true);
}
};
const signout = cb => {
sessionStorage.removeItem("key");
setUser(false);
cb();
};
function checkPassphrase() {
if (checkword === "" || checkword === null || checkword === "null") {
console.error("checkword is empty !");
return false;
}
localStorage.setItem("checkword", checkword);
const key = ""+sessionStorage.getItem("key");
if (key === "" || key === null || key === "null") {
console.error("key is empty 🤔 !");
return false;
}
const encryptStorage = new EncryptStorage(key);
const decrypted_word = encryptStorage.decrypt("checkword");
return decrypted_word === word;
}
const Error = function() {
if (error) {
return (
<Alert severity="error">
<AlertTitle>Erreur</AlertTitle>
La phrase de passe ne correspond pas.
</Alert>
);
}
return (<div></div>);
}
const LoadButton = function() {
return allLoaded ? (<></>) : (
<Button variant="outlined" size="small" sx={{align: "right"}} onClick={() => loadPages.current()}>
Charger les pages localement
</Button>
);
}
const AuthButton = function() {
const history = useHistory();
return user ? (
<p>
Bienvenue !{" "}
<Button variant="outlined" size="small" sx={{align: "right"}} onClick={() => {
signout(() => history.push("/diary/public"));
}}>
Fermer mon carnet à clef
</Button>
</p>
) : (
<p>
Votre carnet est fermé.{" "}
<Link to="/diary/public/pages">Voir vos pages</Link>
</p>
);
}
function updatePassphrase(newPassphrase) {
setPassphrase(newPassphrase);
if (checkPassphrase()) {
isError(false);
setUser(true);
signin(() => {
history.push({ pathname: "/diary/public/pages" });
})
} else {
isError(true);
}
}
function PrivateRoute({ children, ...rest }) {
return (
<Route
{...rest}
render={({ location }) =>
user ? (
children
) : (
<Redirect
to={{
pathname: "/diary/public/pass",
state: { from: location }
}}
/>
)
}
/>
);
}
function PromptPage() {
return (<Prompt open={true} setOpen={updatePassphrase}/>);
}
function getCalendarValuesFromPagesList(pages: IList[]): CalendarHeatmapValuesProp[] {
return pages.map(page => {
const [date, ] = page.date.split(" ");
const splittedDate = date.split("/").map(part => { return parseInt(part, 10);});
return {
id: page.id,
date: new Date(splittedDate[2] as number, splittedDate[1] - 1, splittedDate[0] as number),
event: page.id
};
});
}
function ListPage() {
return (
<div className="col-md-12">
<CalendarHeatmap
values={getCalendarValuesFromPagesList(listPages)}
startDate={startDate}
endDate={new Date()}
showMonthLabels={true}
showWeekdayLabels={true}
showOutOfRangeDays={true}
horizontal={true}
gutterSize={4}
onClick={(value) => alert(value)}
tooltipDataAttrs={{}}
/>
<Pages
pages={listPages}
url={getPageContentUrl}
passphrase={passphrase}
csrf={csrf}
removeUrl={removeUrl}
loadPages={loadPages}
settings={settings}
setAllLoaded={setAllLoaded}
/>
<Divider/>
<PageForm setListPages={setListPages} csrf={csrf} url={postUrl} passphrase={passphrase}/>
</div>
);
}
return (
<div>
<AuthButton />
<LoadButton />
<Error/>
<Divider sx={{height: "20px", mb: "20px", mt:"10px"}}/>
<Switch>
<Route path="/diary/public/pass">
<PromptPage />
</Route>
<PrivateRoute path="/diary/public/pages">
<ListPage />
</PrivateRoute>
</Switch>
</div>
);
}
export default withRouter(App);