Skip to content

Commit

Permalink
✨ export/import profile (#98)
Browse files Browse the repository at this point in the history
  • Loading branch information
haliphax authored Sep 20, 2023
1 parent fac678c commit 1385552
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 41 deletions.
90 changes: 77 additions & 13 deletions src/front-end/scripts/components/profile.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts">
import { defineComponent } from "vue";
import { SessionState } from "../store/types";
const Profile = defineComponent({
data() {
Expand All @@ -14,9 +15,42 @@ const Profile = defineComponent({
},
},
methods: {
exportSession() {
const link = document.createElement("a");
const content = JSON.stringify(this.$store.state.session);
link.href = `data:application/json,${content}`;
link.download = "narf.json";
link.click();
},
importSession() {
console.log(`start ${Date.now()}`);
(this.$refs.file as HTMLInputElement).click();
},
async loadFile() {
const files = (this.$refs.file as HTMLInputElement).files;
if (!files || files.length === 0) return;
if (files.length > 1) return alert("Please select a single file");
const file = files[0];
if (!file.name.endsWith(".json"))
return alert("Please select a JSON file");
const session: SessionState = JSON.parse(await file.text());
this.$store.commit("session.settings", session);
this.name = session.name;
requestAnimationFrame(() => {
this.upToDate = true;
alert("Profile imported successfully");
});
},
submit() {
this.$store.commit("session.settings.name", this.name);
this.upToDate = true;
alert("Profile updated");
},
},
});
Expand All @@ -25,25 +59,55 @@ export default Profile;
</script>

<template>
<form @submit.prevent="submit()">
<fieldset class="grid">
<legend>Profile</legend>
<span>
<label for="name">Name:</label>
<input id="name" v-model="name" type="text" required />
</span>
<span>
<button type="submit" :disabled="upToDate">Update</button>
</span>
</fieldset>
</form>
<div>
<form @submit.prevent="submit()">
<fieldset class="grid">
<legend>Profile</legend>
<span>
<label for="name">Name:</label>
<input id="name" v-model="name" type="text" required />
</span>
<span>
<button type="submit" :disabled="upToDate">✅ Update</button>
</span>
</fieldset>
</form>
<ul class="unstyled grid">
<li>
<button @click="exportSession()">💾 Export</button>
</li>
<li>
<button @click="importSession()">📥 Import</button>
<input
ref="file"
accept="application/json"
class="no"
multiple
type="file"
@change="loadFile()"
/>
</li>
</ul>
</div>
</template>

<style lang="less" scoped>
@import "../../styles/breakpoints.less";
ul.unstyled {
margin-top: var(--space-l);
}
ul li {
grid-area: 1 / span 2;
}
li button {
width: 100%;
}
@media @breakpoint_m {
.grid > span {
fieldset.grid > span {
grid-area: 1 / span 2;
}
}
Expand Down
10 changes: 9 additions & 1 deletion src/front-end/scripts/store/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,20 @@ const SESSION_PREFIX = `${LOCALSTORAGE_GLOBAL_PREFIX}session.`;

const keys = {
darkMode: `${SESSION_PREFIX}darkMode`,
sessionId: `${SESSION_PREFIX}sessionId`,
name: `${SESSION_PREFIX}name`,
sessionId: `${SESSION_PREFIX}sessionId`,
};

const session: Module<SessionState, StoreState> = {
mutations: {
"session.settings"(state, payload: SessionState) {
state.id = payload.id;
state.name = payload.name;
state.settings = payload.settings;
localStorage.setItem(keys.darkMode, payload.settings.darkMode.toString());
localStorage.setItem(keys.sessionId, payload.id);
localStorage.setItem(keys.name, payload.name.toString());
},
"session.settings.darkMode"(state, payload: boolean) {
state.settings.darkMode = payload;
localStorage.setItem(keys.darkMode, payload.toString());
Expand Down
65 changes: 38 additions & 27 deletions src/front-end/styles/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,7 @@ body {
min-height: 100%;
}

button {
background-color: var(--color-bg);
color: var(--color-fg);
cursor: pointer;
font-size: 115%;
}

button[disabled] {
cursor: not-allowed;
text-decoration: line-through;
}
/* links */

a,
a:link {
Expand All @@ -86,19 +76,19 @@ a:visited {
opacity: 0.9;
}

code {
background-color: var(--color-bg);
padding-inline: var(--space-m);
}
/* buttons */

label,
summary {
button {
background-color: var(--color-bg);
color: var(--color-fg);
cursor: pointer;
font-weight: bold;
font-size: 115%;
padding: var(--space-s) var(--space-l);
}

:is(ol, ul):not(.unstyled) li:not(:last-child) {
margin-bottom: var(--space-s);
button[disabled] {
cursor: not-allowed;
text-decoration: line-through;
}

/* details */
Expand Down Expand Up @@ -158,6 +148,19 @@ legend {
padding-inline: var(--space-s);
}

/* lists */

:is(ol, ul).unstyled {
list-style-type: none;
list-style-position: inside;
margin: 0;
padding: 0;
}

:is(ol, ul):not(.unstyled) li:not(:last-child) {
margin-bottom: var(--space-s);
}

/* application wrapper */
#app {
width: 100%;
Expand All @@ -174,21 +177,29 @@ legend {
display: inline-block;
}

.no {
display: none;
}

.right {
text-align: right;
}

/* screen-reader only */
.sr {
/* screen reader only */
right: 100vw;
position: absolute;
}

/* unstyled list */
/* misc elements */

:is(ol, ul).unstyled {
list-style-type: none;
list-style-position: inside;
margin: 0;
padding: 0;
code {
background-color: var(--color-bg);
padding-inline: var(--space-m);
}

label,
summary {
cursor: pointer;
font-weight: bold;
}

0 comments on commit 1385552

Please sign in to comment.