Skip to content

Commit

Permalink
feat(setting): implement basic local storage data exporter/importer
Browse files Browse the repository at this point in the history
refs #56
  • Loading branch information
ygrishajev committed May 22, 2024
1 parent fd781cd commit 34b1cf4
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React, { FC, useCallback, useRef } from "react";
import { Download, Upload } from "iconoir-react";
import { Button } from "@src/components/ui/button";

export type LocalData = Record<string, any>;

interface LocalDataManagerProps {
read: () => LocalData;
write: (data: LocalData) => void;
onDone?: () => void;
}

export const LocalDataManagerComponent: FC<LocalDataManagerProps> = ({ read, write, onDone }) => {
const ref = useRef<HTMLInputElement>(null);

const triggerFileUpload = useCallback(() => {
ref.current?.click();
}, [ref.current]);

const importLocalData = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (!file) return;

const reader = new FileReader();
reader.onload = () => {
const data = JSON.parse(reader.result as string);
write(data);

if (typeof onDone === "function") {
onDone();
}
};
reader.readAsText(file);
}, []);

const downloadLocalData = useCallback(() => {
const data = JSON.stringify(read());
const blob = new Blob([data], { type: "application/json" });
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = "console.akash.network.data.json";
link.click();
}, []);

return (
<div className="grid-col-1 mt-4 grid gap-4 md:grid-cols-2">
<Button onClick={downloadLocalData} size="sm" className="mt-6">
<Download className="text-sm" />
Export Local Data
</Button>

<input onChange={importLocalData} type="file" ref={ref} hidden accept=".json" />

<Button onClick={triggerFileUpload} size="sm" className="mt-6">
<Upload className="text-sm" />
Import Local Data
</Button>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { LocalData, LocalDataManagerComponent } from "./LocalDataManager.component";
import React, { useCallback } from "react";

export const LocalDataManagerContainer = () => {
const importLocalData = useCallback((data: LocalData) => {
Object.keys(data).forEach(key => {
localStorage.setItem(key, data[key]);
});
}, []);

const readLocalData = useCallback(() => {
return localStorage;
}, []);

const reload = () => window.location.reload();

return <LocalDataManagerComponent read={readLocalData} write={importLocalData} onDone={reload} />;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { LocalDataManagerContainer as LocalDataManager } from "./LocalDataManager.container";
2 changes: 2 additions & 0 deletions deploy-web/src/components/settings/SettingsContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { SelectNetworkModal } from "./SelectNetworkModal";
import { SettingsForm } from "./SettingsForm";
import { ColorModeSelect } from "./ColorModeSelect";
import { NextSeo } from "next-seo";
import { LocalDataManager } from "@src/components/settings/LocalDataManager";

type Props = {};

Expand Down Expand Up @@ -48,6 +49,7 @@ export const SettingsContainer: React.FunctionComponent<Props> = ({}) => {

<Fieldset label="General">
<ColorModeSelect />
<LocalDataManager />
</Fieldset>
</div>

Expand Down
2 changes: 1 addition & 1 deletion deploy-web/src/components/settings/SettingsLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const SettingsLayout: React.FunctionComponent<Props> = ({ children, page,
</TabsTrigger>
</TabsList>

<div className="flex flex-wrap items-center py-4 mt-4">
<div className="mt-4 flex flex-wrap items-center py-4">
<Title>{title}</Title>
{headerActions}
</div>
Expand Down

0 comments on commit 34b1cf4

Please sign in to comment.