Koito/client/app/components/modals/ExportModal.tsx
Gabe Farrell c16b557c21
feat: v0.0.10 (#23)
* feat: single SOT for themes + basic custom support

* fix: adjust colors for yuu theme

* feat: Allow loading of environment variables from file (#20)

* feat: allow loading of environment variables from file

* Panic if a file for an environment variable cannot be read

* Use log.Fatalf + os.Exit instead of panic

* fix: remove supurfluous call to os.Exit()

---------

Co-authored-by: adaexec <nixos-git.s1pht@simplelogin.com>
Co-authored-by: Gabe Farrell <90876006+gabehf@users.noreply.github.com>

* chore: add pr test workflow

* chore: changelog

* feat: make all activity grids configurable

* fix: adjust activity grid style

* fix: make background gradient consistent size

* revert: remove year from activity grid opts

* style: adjust top item list min size to 200px

* feat: add support for custom themes

* fix: stabilized the order of top items

* chore: update changelog

* feat: native import & export

* fix: use correct request body for alias requests

* fix: clear input when closing edit modal

* chore: changelog

* docs: make endpoint clearer for some apps

* feat: add ui and handler for export

* fix: fix pr test workflow

---------

Co-authored-by: adaexec <78047743+adaexec@users.noreply.github.com>
Co-authored-by: adaexec <nixos-git.s1pht@simplelogin.com>
2025-06-18 08:48:19 -04:00

45 lines
No EOL
1.3 KiB
TypeScript

import { useState } from "react";
import { AsyncButton } from "../AsyncButton";
import { getExport } from "api/api";
export default function ExportModal() {
const [loading, setLoading] = useState(false)
const [error, setError] = useState('')
const handleExport = () => {
setLoading(true)
fetch(`/apis/web/v1/export`, {
method: "GET"
})
.then(res => {
if (res.ok) {
res.blob()
.then(blob => {
const url = window.URL.createObjectURL(blob)
const a = document.createElement("a")
a.href = url
a.download = "koito_export.json"
document.body.appendChild(a)
a.click()
a.remove()
window.URL.revokeObjectURL(url)
setLoading(false)
})
} else {
res.json().then(r => setError(r.error))
setLoading(false)
}
}).catch(err => {
setError(err)
setLoading(false)
})
}
return (
<div>
<h2>Export</h2>
<AsyncButton loading={loading} onClick={handleExport}>Export Data</AsyncButton>
{error && <p className="error">{error}</p>}
</div>
)
}