add restore functionality

This commit is contained in:
Calli
2023-06-23 22:20:58 +03:00
parent 808d983bd1
commit ed13e73587
7 changed files with 120 additions and 2 deletions

View File

@@ -1,4 +1,4 @@
import { CharacterContext } from "@/app/context/Context";
import { CharacterContext, SessionContext } from "@/app/context/Context";
import { Button } from "@mui/material";
import { useContext } from "react";
@@ -9,7 +9,7 @@ export const DowloadButton = () => {
href={`data:text/json;charset=utf-8,${encodeURIComponent(
JSON.stringify(characters)
)}`}
download="pi-avanto-tk-characters.json"
download={`eve-pi-characters.json`}
>
Backup
</Button>

View File

@@ -0,0 +1,21 @@
import { Box, Button } from "@mui/material";
import { useState } from "react";
import { UploadDialog } from "./UploadDialog";
export const UploadButton = () => {
const [uploadDialogOpen, setUploadDialogOpen] = useState(false);
return (
<Box>
<Button
style={{ width: "100%" }}
onClick={() => setUploadDialogOpen(true)}
>
Restore
</Button>
<UploadDialog
open={uploadDialogOpen}
closeDialog={() => setUploadDialogOpen(false)}
/>
</Box>
);
};

View File

@@ -0,0 +1,72 @@
import DialogTitle from "@mui/material/DialogTitle";
import Dialog from "@mui/material/Dialog";
import Button from "@mui/material/Button";
import { DialogActions, DialogContent, Typography } from "@mui/material";
import { useContext, useEffect, useState } from "react";
import { CharacterContext } from "@/app/context/Context";
import { AccessToken } from "@/types";
export const UploadDialog = ({
open,
closeDialog,
}: {
open: boolean;
closeDialog: () => void;
}) => {
const [file, setFile] = useState();
const fileReader = new FileReader();
const { restoreCharacters } = useContext(CharacterContext);
const error = new Error("Invalid input");
const validate = (characters: AccessToken[]) => {
characters.forEach((c) => {
if (!c.access_token) throw error;
if (!c.expires_at) throw error;
if (!c.refresh_token) throw error;
if (!c.character) throw error;
if (!c.character.characterId) throw error;
if (!c.character.name) throw error;
});
return characters;
};
useEffect(() => {
if (file) {
fileReader.onload = (event) => {
if (!event || event.target === null) return;
const jsonOutput = event.target.result?.toString();
if (jsonOutput) restoreCharacters(validate(JSON.parse(jsonOutput)));
closeDialog();
};
fileReader.readAsText(file);
}
}, [file]);
const changeHandler = (event: any) => {
setFile(event.target.files[0]);
};
return (
<Dialog open={open} onClose={closeDialog}>
<DialogTitle>Restore your character list</DialogTitle>
<DialogContent>
<Typography>
The list must be exported from the same EVE PI instance to work!
</Typography>
<input
type="file"
name="file"
accept=".json"
onChange={changeHandler}
style={{ paddingTop: "1rem" }}
/>
</DialogContent>
<DialogActions>
<Button onClick={closeDialog}>Close</Button>
</DialogActions>
</Dialog>
);
};

View File

@@ -7,6 +7,7 @@ import { CharacterContext } from "../context/Context";
import { DowloadButton } from "./Backup/DowloadButton";
import { DiscordButton } from "./Discord/DiscordButton";
import { GitHubButton } from "./Github/GitHubButton";
import { UploadButton } from "./Backup/UploadButton";
interface Grouped {
[key: string]: AccessToken[];
@@ -28,6 +29,7 @@ export const MainGrid = ({ sessionReady }: { sessionReady: boolean }) => {
<Stack direction="row" spacing={1}>
<LoginButton />
<DowloadButton />
<UploadButton />
<DiscordButton />
<GitHubButton />
</Stack>

View File

@@ -5,10 +5,12 @@ export const CharacterContext = createContext<{
characters: AccessToken[];
deleteCharacter: (character: AccessToken) => void;
updateCharacter: (character: AccessToken, update: CharacterUpdate) => void;
restoreCharacters: (characters: AccessToken[]) => void;
}>({
characters: [],
deleteCharacter: () => {},
updateCharacter: () => {},
restoreCharacters: () => {},
});
export const SessionContext = createContext<{

View File

@@ -73,6 +73,10 @@ const Home = () => {
return characters;
};
const restoreCharacters = (characters: AccessToken[]) => {
refreshSession(characters).then(saveCharacters).then(setCharacters);
};
// Initialize EVE PI
useEffect(() => {
fetch("api/env")
@@ -106,6 +110,7 @@ const Home = () => {
characters,
deleteCharacter,
updateCharacter,
restoreCharacters,
}}
>
<MainGrid sessionReady={sessionReady} />