diff options
| author | Leonardo Bishop <me@leonardobishop.com> | 2024-03-13 18:17:07 +0000 |
|---|---|---|
| committer | Leonardo Bishop <me@leonardobishop.com> | 2024-03-13 18:17:55 +0000 |
| commit | 825d2cadee4ddf34d0dde8c278fc8e8a99e95b95 (patch) | |
| tree | 92be3e83ad6af8aa9d7f8861f8c4cd3d8ae4f486 /components | |
| parent | ba28c0148cab26fcaf523e84731ffb7c416b3338 (diff) | |
Add export modal
Diffstat (limited to 'components')
| -rw-r--r-- | components/base/Modal.vue | 6 | ||||
| -rw-r--r-- | components/export/ExportButton.vue | 15 | ||||
| -rw-r--r-- | components/export/ExportModal.vue | 173 | ||||
| -rw-r--r-- | components/header/SiteHeader.vue | 10 | ||||
| -rw-r--r-- | components/loader/LoaderImportButton.vue | 7 |
5 files changed, 208 insertions, 3 deletions
diff --git a/components/base/Modal.vue b/components/base/Modal.vue index f7b6df3..f3a32d0 100644 --- a/components/base/Modal.vue +++ b/components/base/Modal.vue @@ -62,7 +62,11 @@ const model = defineModel(); } .header { - border-bottom: 1px solid var(--color-border); margin-bottom: 1rem; } + +:deep(.header) h2 { + font-weight: 600; + border-bottom: none; +} </style>
\ No newline at end of file diff --git a/components/export/ExportButton.vue b/components/export/ExportButton.vue new file mode 100644 index 0000000..51c4b0a --- /dev/null +++ b/components/export/ExportButton.vue @@ -0,0 +1,15 @@ +<script setup lang="ts"> +import type ExportModal from './ExportModal.vue'; + +const exportModal = ref<InstanceType<typeof ExportModal> | null>(null); + +const openExportModal = async () => { + exportModal.value?.open(); +} +</script> + +<template> + <Button type="solid" :icon="['fas', 'file-export']" label="Save / Export" @click="openExportModal" /> + + <ExportModal ref="exportModal" /> +</template>
\ No newline at end of file diff --git a/components/export/ExportModal.vue b/components/export/ExportModal.vue new file mode 100644 index 0000000..8bc6936 --- /dev/null +++ b/components/export/ExportModal.vue @@ -0,0 +1,173 @@ +<script setup lang="ts"> +const session = useSessionStore(); + +const showModal = ref(false); + +const open = () => { + showModal.value = true; +} + +const { canUseFsApi } = getBrowserCapabilities(); +const isUsingFsMode = computed(() => session.getSessionType() === 'filesystem'); + +defineExpose({ + open +}) +</script> + +<template> + <Modal v-model="showModal"> + <template v-slot:header> + <h2>Export quest configuration</h2> + </template> + + <div id="export"> + <p>Use one of the options below to export quest configuration data.</p> + + <div id="export-options"> + <div class="row-container export-row"> + <div id="icon"> + <font-awesome-icon :icon="['fas', 'hard-drive']" /> + </div> + + <div id="description"> + <p id="subtitle">Write to File System</p> + <p>Write directly to the Quests data directory you opened.</p> + <p class="error" v-if="!canUseFsApi"> + <font-awesome-icon :icon="['fas', 'xmark']" /> + Your browser is not capable of using this mode. + </p> + <p class="error" v-if="canUseFsApi && !isUsingFsMode"> + <font-awesome-icon :icon="['fas', 'xmark']" /> + You did not start this session by importing from file system. + </p> + </div> + + <div id="button-group"> + <Button type="solid" label="Continue" :disabled="true" /> + </div> + </div> + <div class="row-container export-row"> + <div id="icon"> + <font-awesome-icon :icon="['fas', 'upload']" /> + </div> + + <div id="description"> + <p id="subtitle">Send to Server</p> + <p>Upload your quest configuration to the server, which can be downloaded and automatically applied in-game. + </p> + </div> + + <div id="button-group"> + <Button type="solid" label="Continue" :disabled="true" /> + </div> + </div> + <div class="row-container export-row"> + <div id="icon"> + <font-awesome-icon :icon="['fas', 'file-zipper']" /> + </div> + + <div id="description"> + <p id="subtitle">Download as ZIP</p> + <p>Download your quest configuration as a ZIP file.</p> + </div> + + <div id="button-group"> + <Button type="solid" label="Continue" :disabled="true" /> + </div> + </div> + </div> + </div> + + <div id="controls" class="control-group"> + <Button :icon="['fas', 'xmark']" :label="'Cancel'" @click="showModal = false"></Button> + </div> + </Modal> +</template> + +<style scoped> +#export-container { + display: flex; + justify-content: center; + width: 100%; + height: 100%; +} + +#export-options { + width: 100%; + display: flex; + flex-direction: column; +} + +.row-container { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + width: 100%; + padding: 1rem 0; + gap: 0.5rem; + + #icon { + flex-basis: 3rem; + flex-shrink: 0; + font-size: 2rem; + color: var(--color-text-mute); + display: flex; + align-items: center; + justify-content: center; + } + + #description { + flex-grow: 1; + } + + #button-group { + display: flex; + flex-direction: column; + align-items: flex-end; + } +} + +.export-row { + border-bottom: 1px solid var(--color-border-soft); +} + +.export-row:first-child { + border-top: 1px solid var(--color-border-soft); +} + +.error { + color: var(--color-false); +} + +#export { + display: flex; + flex-direction: column; + gap: 1rem; +} + +#title { + font-weight: bold; + font-size: 1.5rem; +} + +#subtitle { + font-weight: bold; + font-size: 1.1rem; +} + +b { + font-weight: bold; +} + +hr { + width: 100%; +} + +#controls { + display: flex; + justify-content: flex-end; + margin-top: 1rem; +} +</style>
\ No newline at end of file diff --git a/components/header/SiteHeader.vue b/components/header/SiteHeader.vue index afd85b8..22ee209 100644 --- a/components/header/SiteHeader.vue +++ b/components/header/SiteHeader.vue @@ -1,7 +1,11 @@ <script setup land="ts"> +const session = useSessionStore(); + const navigateHome = () => { navigateTo('/'); } + +const sessionType = computed(() => session.getSessionType()); </script> <template> @@ -14,8 +18,12 @@ const navigateHome = () => { <code>Preview</code> </div> - <div id="controls"> + <div id="controls" v-if="sessionType === 'none'"> + <LoaderImportButton :isPrimaryAction="true" /> + </div> + <div id="controls" v-if="sessionType !== 'none'"> <LoaderImportButton /> + <ExportButton /> </div> </header> </template> diff --git a/components/loader/LoaderImportButton.vue b/components/loader/LoaderImportButton.vue index 48bcb8d..ff6d0ad 100644 --- a/components/loader/LoaderImportButton.vue +++ b/components/loader/LoaderImportButton.vue @@ -1,9 +1,14 @@ <script setup lang="ts"> +defineProps({ + isPrimaryAction: Boolean +}) + const navigateToImport = async () => { navigateTo('/import'); } </script> <template> - <Button type="solid" :icon="['fas', 'file-import']" label="Import" @click="navigateToImport" /> + <Button :type="isPrimaryAction ? 'solid' : 'text'" :icon="['fas', 'file-import']" label="Import" + @click="navigateToImport" /> </template>
\ No newline at end of file |
