Skip to content

Commit

Permalink
feat: create backup page
Browse files Browse the repository at this point in the history
  • Loading branch information
AlejandroAkbal committed Jun 19, 2023
1 parent 6652916 commit c93bef1
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 288 deletions.
27 changes: 27 additions & 0 deletions components/layout/PageHeader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<script lang="ts" setup>
export interface PageHeaderProps {
as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
}
const props = withDefaults(defineProps<PageHeaderProps>(), {
as: 'h1'
})
</script>

<template>
<div>
<component
:is="props.as"
class="text-2xl font-bold leading-10 tracking-tight text-base-content-highlight"
>
<slot name="title" />
</component>

<p
v-if="$slots.text"
class="text-base-content"
>
<slot name="text" />
</p>
</div>
</template>
163 changes: 163 additions & 0 deletions pages/premium/backup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<script lang="ts" setup>
import { ArrowDownTrayIcon, ArrowUturnLeftIcon } from '@heroicons/vue/24/solid'
import PageHeader from '~/components/layout/PageHeader.vue'
import { toast } from 'vue-sonner'
import type { ISavedPost } from '~/store/SavedPosts'
import type { ITagCollection } from 'assets/js/tagCollection.dto'
interface IBackupState {
version: number
saved_posts: ISavedPost[]
tag_collections: ITagCollection[]
settings: undefined
}
const fileInputElement = ref<HTMLInputElement | null>(null)
function downloadBlob(blob: Blob, filename: string) {
const objectURL = window.URL.createObjectURL(blob)
// Create anchor element
const anchorElement = document.createElement('a')
anchorElement.href = objectURL
anchorElement.target = '_blank'
anchorElement.download = filename
anchorElement.style.display = 'none'
// Download
anchorElement.click()
// Clean up
anchorElement.remove()
window.URL.revokeObjectURL(objectURL)
}
function createBackup() {
const currentDateString = new Date()
.toLocaleString([], {
timeZone: 'UTC',
hour12: false,
second: '2-digit',
minute: '2-digit',
hour: '2-digit',
day: '2-digit',
month: '2-digit',
year: 'numeric'
})
.replaceAll(', ', '_')
.replaceAll('/', '-')
.replaceAll(':', '-')
// TODO: Do versioning, or maybe not?
const STATE: IBackupState = {
version: 1,
saved_posts: [],
tag_collections: [],
settings: undefined
}
const blob = new Blob([JSON.stringify(STATE)], { type: 'application/json' })
const fileName = `R34App_${currentDateString}_Backup.json`
downloadBlob(blob, fileName)
}
async function restoreBackup() {
if (!fileInputElement.value) {
toast.error('No file selected')
return
}
const file = fileInputElement.value.files?.[0]
if (!file) {
toast.error('No file selected')
return
}
const backupData: IBackupState = JSON.parse(await file.text())
if (backupData.version !== 1) {
toast.error('Invalid backup file')
return
}
if (backupData.saved_posts) {
// TODO
}
if (backupData.tag_collections) {
// TODO
}
if (backupData.settings) {
// TODO
}
toast.success('Backup restored')
}
useSeoMeta({
title: 'Backup'
})
definePageMeta({ middleware: 'auth' })
</script>

<template>
<main class="container relative mx-auto max-w-3xl flex-1 px-4 sm:px-6 lg:px-8">
<!-- -->

<!-- Header -->
<PageHeader class="mt-4">
<template #title>Backup & Restore</template>
<template #text>
<div class="text-sm">
Backup your saved posts, tag collections and settings.

<span class="italic"> This is a manual process. Remember to backup your data regularly. </span>
</div>
</template>
</PageHeader>

<section class="mt-8 flex justify-around">
<!-- -->

<!-- Backup -->
<button
class="focus-visible:focus-util hover:hover-text-util hover:hover-bg-util inline-flex min-w-[5rem] flex-col items-center gap-1.5 rounded-md p-2 ring-1 ring-base-0/20"
type="button"
@click="createBackup"
>
<ArrowDownTrayIcon class="h-6 w-6" />

Backup
</button>

<!-- Restore -->
<input
ref="fileInputElement"
accept="application/json"
style="display: none"
type="file"
@change="restoreBackup"
/>

<button
class="focus-visible:focus-util hover:hover-text-util hover:hover-bg-util inline-flex min-w-[5rem] flex-col items-center gap-1.5 rounded-md p-2 ring-1 ring-base-0/20"
type="button"
@click="$refs.fileInputElement.click()"
>
<ArrowUturnLeftIcon class="h-6 w-6" />

Restore
</button>
</section>
</main>
</template>
116 changes: 0 additions & 116 deletions pages/premium/backup.vue.bak

This file was deleted.

Loading

0 comments on commit c93bef1

Please sign in to comment.