diff --git a/package-lock.json b/package-lock.json
index 7bcd6f7..f4efe74 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,7 +15,8 @@
"laravel-vue-i18n": "^2.7.1",
"openseadragon": "^4.1.0",
"pinia": "^2.1.6",
- "vue": "^3.3.4",
+ "pinia-plugin-persistedstate": "^3.2.0",
+ "vue": "^3.3.7",
"vue-router": "^4.2.5",
"vue3-carousel": "^0.3.1"
},
@@ -24,7 +25,7 @@
"@tsconfig/node18": "^18.2.2",
"@types/node": "^18.18.5",
"@types/openseadragon": "^3.0.8",
- "@vitejs/plugin-vue": "^4.2.3",
+ "@vitejs/plugin-vue": "^4.4.0",
"@vue/eslint-config-prettier": "^8.0.0",
"@vue/eslint-config-typescript": "^12.0.0",
"@vue/tsconfig": "^0.4.0",
@@ -34,6 +35,7 @@
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-prettier-vue": "^4.2.0",
"eslint-plugin-vue": "^9.17.0",
+ "husky": "^8.0.3",
"lodash": "^4.17.21",
"npm-run-all2": "^6.1.1",
"prettier": "^3.0.3",
@@ -43,9 +45,9 @@
"unplugin-auto-import": "^0.16.7",
"unplugin-vue-components": "^0.25.2",
"unplugin-vue-router": "^0.7.0",
- "vite": "^4.4.5",
+ "vite": "^4.5.0",
"vite-plugin-rewrite-all": "^1.0.1",
- "vue-tsc": "^1.8.19"
+ "vue-tsc": "^1.8.22"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@@ -3368,6 +3370,21 @@
"node": ">=14.18.0"
}
},
+ "node_modules/husky": {
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz",
+ "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==",
+ "dev": true,
+ "bin": {
+ "husky": "lib/bin.js"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/typicode"
+ }
+ },
"node_modules/ignore": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
@@ -4612,6 +4629,14 @@
}
}
},
+ "node_modules/pinia-plugin-persistedstate": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/pinia-plugin-persistedstate/-/pinia-plugin-persistedstate-3.2.0.tgz",
+ "integrity": "sha512-tZbNGf2vjAQcIm7alK40sE51Qu/m9oWr+rEgNm/2AWr1huFxj72CjvpQcIQzMknDBJEkQznCLAGtJTIcLKrKdw==",
+ "peerDependencies": {
+ "pinia": "^2.0.0"
+ }
+ },
"node_modules/pinia/node_modules/vue-demi": {
"version": "0.14.6",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
diff --git a/package.json b/package.json
index def38b6..ad59faa 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,7 @@
"laravel-vue-i18n": "^2.7.1",
"openseadragon": "^4.1.0",
"pinia": "^2.1.6",
+ "pinia-plugin-persistedstate": "^3.2.0",
"vue": "^3.3.7",
"vue-router": "^4.2.5",
"vue3-carousel": "^0.3.1"
diff --git a/src/app.ts b/src/app.ts
index 6e7d201..5d2d569 100644
--- a/src/app.ts
+++ b/src/app.ts
@@ -1,14 +1,14 @@
-import './bootstrap'
-import './css/style.css'
-
-import App from './App.vue'
+import '@/bootstrap'
+import '@/css/style.css'
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router/auto'
import { i18nVue } from 'laravel-vue-i18n'
import { createPinia } from 'pinia'
+import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import * as Sentry from '@sentry/vue'
+import App from '@/App.vue'
import { useLocaleStore } from '@/stores/LocaleStore'
import { useHistoryStore } from '@/stores/HistoryStore'
@@ -29,7 +29,10 @@ const app = createApp(App)
Sentry.init({ app, dsn: import.meta.env.VITE_SENTRY_DSN })
app.use(router)
-app.use(createPinia())
+
+const pinia = createPinia()
+pinia.use(piniaPluginPersistedstate)
+app.use(pinia)
const localeStore = useLocaleStore()
app.use(i18nVue, {
diff --git a/src/components/author/AuthorDetails.vue b/src/components/author/AuthorDetails.vue
index 62141a9..f639709 100644
--- a/src/components/author/AuthorDetails.vue
+++ b/src/components/author/AuthorDetails.vue
@@ -3,7 +3,9 @@
diff --git a/src/components/author/AuthorSummary.vue b/src/components/author/AuthorSummary.vue
index c9fa6d1..32e308b 100644
--- a/src/components/author/AuthorSummary.vue
+++ b/src/components/author/AuthorSummary.vue
@@ -13,7 +13,9 @@
diff --git a/src/components/author/AuthorityDetails.vue b/src/components/author/AuthorityDetails.vue
index 49572bf..d7a10b4 100644
--- a/src/components/author/AuthorityDetails.vue
+++ b/src/components/author/AuthorityDetails.vue
@@ -42,12 +42,14 @@ import axios from 'axios'
import ItemPreview from '@/components/general/ItemPreview.vue'
import ItemImage from '@/components/general/ItemImage.vue'
+import Authority from '@/models/Authority'
+import Item from '@/models/Item'
const props = defineProps<{
- authority: any // TODO: add model
+ authority: Authority
}>()
-const relatedItems = ref([]) // TODO: add model
-const previewItem = ref(null) // TODO: add model
+const relatedItems = ref- ([])
+const previewItem = ref
- (null)
const isLoading = ref(true)
onMounted(async () => {
@@ -56,7 +58,7 @@ onMounted(async () => {
const response = await axios.get(
`/api/related_items/${props.authority.related_items.join(',')}`
)
- relatedItems.value = response.data.data
+ relatedItems.value = response.data.data.map((item: any) => new Item(item))
} catch (error) {
console.error(error)
} finally {
diff --git a/src/components/author/AuthoritySummary.vue b/src/components/author/AuthoritySummary.vue
index 5a15c63..bb23b0c 100644
--- a/src/components/author/AuthoritySummary.vue
+++ b/src/components/author/AuthoritySummary.vue
@@ -16,7 +16,9 @@
diff --git a/src/components/bucketlist/Bucketlist.vue b/src/components/bucketlist/Bucketlist.vue
index 86ed56e..08fcda5 100644
--- a/src/components/bucketlist/Bucketlist.vue
+++ b/src/components/bucketlist/Bucketlist.vue
@@ -9,8 +9,8 @@
unlocked
? $t('All artworks found')
: $t(':found of :all artworks found', {
- found: found.length,
- all: bucketlist.items.length,
+ found: String(found?.length ?? 0),
+ all: String(bucketlist.items.length ?? 0),
})
}}
@@ -58,7 +58,7 @@
-
+
{{ $t('Found') }}
@@ -82,13 +82,14 @@ import ItemThumbnail from '@/components/general/ItemThumbnail.vue'
import LockedItemThumbnail from '@/components/bucketlist/LockedItemThumbnail.vue'
import ResponsiveImageWithSizes from '@/components/general/ResponsiveImageWithSizes.vue'
import Thumbnail from '@/components/general/Thumbnail.vue'
+import Bucketlist from '@/models/Bucketlist'
const props = defineProps<{
id: string
}>()
const bucketlistStore = useBucketlistStore()
const interactionStore = useInteractionStore()
-const bucketlist = ref(null) // TODO: add model
+const bucketlist = ref(null)
const found = computed(() => {
return bucketlist.value?.items.filter((item) => interactionStore.isItemViewed(item.id))
@@ -98,10 +99,10 @@ const notFound = computed(() => {
return bucketlist.value?.items.filter((item) => !interactionStore.isItemViewed(item.id))
})
-const unlocked = computed(() => !notFound.value.length)
+const unlocked = computed(() => !notFound.value?.length)
onMounted(async () => {
- bucketlist.value = bucketlistStore.get(props.id)
+ bucketlist.value = bucketlistStore.get(props.id)!
bucketlist.value = await bucketlistStore.load(props.id)
})
diff --git a/src/components/bucketlist/LockedItemThumbnail.vue b/src/components/bucketlist/LockedItemThumbnail.vue
index 40a491d..519fe67 100644
--- a/src/components/bucketlist/LockedItemThumbnail.vue
+++ b/src/components/bucketlist/LockedItemThumbnail.vue
@@ -17,8 +17,9 @@
diff --git a/src/components/general/ImageLightbox.vue b/src/components/general/ImageLightbox.vue
index f0e5325..e39ba07 100644
--- a/src/components/general/ImageLightbox.vue
+++ b/src/components/general/ImageLightbox.vue
@@ -16,7 +16,7 @@
@@ -42,16 +42,18 @@
diff --git a/src/components/general/ResponsiveImage.vue b/src/components/general/ResponsiveImage.vue
index a59104d..9b6aaa7 100644
--- a/src/components/general/ResponsiveImage.vue
+++ b/src/components/general/ResponsiveImage.vue
@@ -3,7 +3,9 @@
diff --git a/src/components/general/ResponsiveImageWithSizes.vue b/src/components/general/ResponsiveImageWithSizes.vue
index d08d705..a961df6 100644
--- a/src/components/general/ResponsiveImageWithSizes.vue
+++ b/src/components/general/ResponsiveImageWithSizes.vue
@@ -11,8 +11,10 @@
diff --git a/src/components/general/VideoSummary.vue b/src/components/general/VideoSummary.vue
index 1fc23ef..4ebf2ff 100644
--- a/src/components/general/VideoSummary.vue
+++ b/src/components/general/VideoSummary.vue
@@ -13,10 +13,12 @@
diff --git a/src/components/interactions/InteractionItemFavourited.vue b/src/components/interactions/InteractionItemFavourited.vue
index 9cf81e6..d7e135b 100644
--- a/src/components/interactions/InteractionItemFavourited.vue
+++ b/src/components/interactions/InteractionItemFavourited.vue
@@ -4,15 +4,15 @@
icon-class="fill-current"
:label="$t('Saved')"
v-bind="props"
- item=""
/>
diff --git a/src/components/interactions/InteractionItemViewed.vue b/src/components/interactions/InteractionItemViewed.vue
index e9279e4..9b8a921 100644
--- a/src/components/interactions/InteractionItemViewed.vue
+++ b/src/components/interactions/InteractionItemViewed.vue
@@ -1,12 +1,13 @@
-
+
diff --git a/src/components/interactions/InteractionPlaceViewed.vue b/src/components/interactions/InteractionPlaceViewed.vue
index 0dae8d5..aec684f 100644
--- a/src/components/interactions/InteractionPlaceViewed.vue
+++ b/src/components/interactions/InteractionPlaceViewed.vue
@@ -13,7 +13,9 @@
diff --git a/src/components/interactions/InteractionSectionViewed.vue b/src/components/interactions/InteractionSectionViewed.vue
index 405be44..f4075e3 100644
--- a/src/components/interactions/InteractionSectionViewed.vue
+++ b/src/components/interactions/InteractionSectionViewed.vue
@@ -13,7 +13,9 @@
diff --git a/src/components/interactions/InteractionStory.vue b/src/components/interactions/InteractionStory.vue
index 4d0fbd4..b92f8b5 100644
--- a/src/components/interactions/InteractionStory.vue
+++ b/src/components/interactions/InteractionStory.vue
@@ -59,18 +59,21 @@
diff --git a/src/components/misc/ZoomViewer.vue b/src/components/misc/ZoomViewer.vue
index 6ee005c..770ed6a 100644
--- a/src/components/misc/ZoomViewer.vue
+++ b/src/components/misc/ZoomViewer.vue
@@ -5,11 +5,13 @@
diff --git a/src/pages/collection.vue b/src/pages/collection.vue
index 5d4369e..cbbc3d3 100644
--- a/src/pages/collection.vue
+++ b/src/pages/collection.vue
@@ -10,13 +10,6 @@
import Bucketlist from '@/components/bucketlist/Bucketlist.vue'
import Timeline from '@/components/timeline/Timeline.vue'
-const route = useRoute()
const itemStore = useItemStore()
const bucketlistId = import.meta.env.VITE_DEFAULT_BUCKETLIST
-
-onMounted(async () => {
- if (route.params.id) {
- itemStore.fetch(route.params.id)
- }
-})
diff --git a/src/pages/index.vue b/src/pages/index.vue
index 7af759f..8be9010 100644
--- a/src/pages/index.vue
+++ b/src/pages/index.vue
@@ -4,9 +4,9 @@
@@ -42,28 +42,31 @@
-
-
diff --git a/src/pages/item/[id].vue b/src/pages/item/[id].vue
index 2e65d02..84b9747 100644
--- a/src/pages/item/[id].vue
+++ b/src/pages/item/[id].vue
@@ -8,18 +8,20 @@
{{
$t(':found of :all artworks found', {
- found: found.length,
- all: bucketlist.items.length,
+ found: String(found?.length ?? 0),
+ all: String(bucketlist?.items.length ?? 0),
})
}}
- {{ $t(unlocked ? 'reward' : 'list') }}
+
@@ -52,9 +54,9 @@
@@ -76,7 +78,7 @@
-
+
@@ -111,6 +113,8 @@
diff --git a/src/pages/locked/[id].vue b/src/pages/locked/[id].vue
index 89ee248..77ef68e 100644
--- a/src/pages/locked/[id].vue
+++ b/src/pages/locked/[id].vue
@@ -26,16 +26,18 @@
diff --git a/src/pages/reward/[id].vue b/src/pages/reward/[id].vue
index a7b8a85..2ff6fa6 100644
--- a/src/pages/reward/[id].vue
+++ b/src/pages/reward/[id].vue
@@ -18,13 +18,13 @@
diff --git a/src/pages/section/[id].vue b/src/pages/section/[id].vue
index eed949b..f6ec6ec 100644
--- a/src/pages/section/[id].vue
+++ b/src/pages/section/[id].vue
@@ -12,10 +12,10 @@
-
![]()
+
- {{ $t('Group of :count artworks', { count: section.items.length }) }}
+ {{ $t('Group of :count artworks', { count: String(section.items.length) }) }}
{{ section.title }}
@@ -24,11 +24,7 @@
{{ $t('More about artworks in the group') }}
-
+
@@ -52,23 +48,23 @@ import HistoryBack from '@/components/misc/HistoryBack.vue'
import ConfirmButton from '@/components/forms/ConfirmButton.vue'
import ItemThumbnail from '@/components/general/ItemThumbnail.vue'
import ItemImage from '@/components/general/ItemImage.vue'
+import Section from '@/models/Section'
-// TODO: why is this duplicated with ref?
-// defineProps<{
-// section: any // TODO: add model
-// }>()
-
-const route = useRoute()
-const interactionStore = useInteractionStore()
+// const interactionStore = useInteractionStore()
const sectionStore = useSectionStore()
-const section = ref
(null)
+const section = ref(null)
+
+const { id } = useParams()
onMounted(async () => {
- const id = route.params.id
section.value = await sectionStore.load(id)
// TODO: where did item come from?
- interactionStore.addSectionViewed(item.value.id)
+ // interactionStore.addSectionViewed(item.value.id)
+})
+
+const codeImage = computed(() => {
+ return `${import.meta.env.VITE_API_URL}/img/${section.value?.code}.svg`
})
diff --git a/src/pages/section/[sectionId]/[id].vue b/src/pages/section/[sectionId]/[id].vue
index ea0b02b..25de5f4 100644
--- a/src/pages/section/[sectionId]/[id].vue
+++ b/src/pages/section/[sectionId]/[id].vue
@@ -8,18 +8,20 @@
{{
$t(':found of :all artworks found', {
- found: found.length,
- all: bucketlist.items.length,
+ found: String(found?.length ?? 0),
+ all: String(bucketlist.items.length ?? 0),
})
}}
- {{ $t(unlocked ? 'reward' : 'list') }}
+
@@ -76,7 +78,7 @@
-
+
@@ -124,22 +126,25 @@ import AuthorSummary from '@/components/author/AuthorSummary.vue'
import AuthorDetails from '@/components/author/AuthorDetails.vue'
import HistoryBack from '@/components/misc/HistoryBack.vue'
import ConfirmButton from '@/components/forms/ConfirmButton.vue'
+import Bucketlist from '@/models/Bucketlist'
+import Item from '@/models/Item'
const route = useRoute()
const bucketlistStore = useBucketlistStore()
const interactionStore = useInteractionStore()
const itemStore = useItemStore()
-const item = ref(null) // TODO: add model
-const bucketlist = ref(null) // TODO: add model
+const item = ref- (null)
+const bucketlist = ref(null)
const found = computed(() =>
- bucketlist.value.items.filter((item) => interactionStore.isItemViewed(item.id))
+ bucketlist.value?.items.filter((item) => interactionStore.isItemViewed(item.id))
)
-const unlocked = computed(() => found.value.length === bucketlist.value.items.length)
+const unlocked = computed(() => found.value?.length === bucketlist.value?.items.length)
onMounted(async () => {
- const id = route.params.id
+ const { id } = useParams()
+
item.value = await itemStore.load(id)
interactionStore.addItemViewed(item.value.id)
const defaultBucketlist = item.value.bucketlists.find(
@@ -153,6 +158,6 @@ onMounted(async () => {
})
const codeImage = computed(() => {
- return `${import.meta.env.VITE_API_URL}/img/${item.value.code}.svg`
+ return `${import.meta.env.VITE_API_URL}/img/${item.value?.code}.svg`
})
diff --git a/src/pages/story/[id].vue b/src/pages/story/[id].vue
index 79ba481..f47b66b 100644
--- a/src/pages/story/[id].vue
+++ b/src/pages/story/[id].vue
@@ -4,9 +4,9 @@
@@ -42,28 +42,31 @@
-
-
diff --git a/src/stores/BucketlistStore.ts b/src/stores/BucketlistStore.ts
index 20b6c9f..b7a3b4f 100644
--- a/src/stores/BucketlistStore.ts
+++ b/src/stores/BucketlistStore.ts
@@ -1,10 +1,10 @@
import { defineStore } from 'pinia'
-import { useStorage } from '@vueuse/core'
-import axios from 'axios'
+
+import Bucketlist from '@/models/Bucketlist'
export const useBucketlistStore = defineStore('BucketlistStore', {
state: () => ({
- bucketlists: useStorage('bucketlists', {}) as any, // TODO: add model
+ bucketlists: {} as Record,
}),
actions: {
get(id: string) {
@@ -13,11 +13,11 @@ export const useBucketlistStore = defineStore('BucketlistStore', {
}
},
async load(id: string) {
- const response = await axios.get(`/api/bucketlists/${id}`)
- return (this.bucketlists[id] = response.data.data)
+ return (this.bucketlists[id] = await Bucketlist.load(id))
},
clearCache() {
- this.bucketlists = []
+ this.bucketlists = {}
},
},
+ persist: true,
})
diff --git a/src/stores/ItemStore.ts b/src/stores/ItemStore.ts
index f911067..3605f03 100644
--- a/src/stores/ItemStore.ts
+++ b/src/stores/ItemStore.ts
@@ -1,11 +1,12 @@
import { defineStore } from 'pinia'
-import { useStorage } from '@vueuse/core'
import axios from 'axios'
+import Item from '@/models/Item'
+
export const useItemStore = defineStore('ItemStore', {
state: () => ({
- items: useStorage('items', {}),
- collectionLink: useStorage('collectionLink', null),
+ items: {} as Record,
+ collectionLink: null,
}),
actions: {
get(id: string) {
@@ -14,8 +15,7 @@ export const useItemStore = defineStore('ItemStore', {
}
},
async load(id: string) {
- const response = await axios.get(`/api/items/${id}`)
- return (this.items[id] = response.data.data)
+ return (this.items[id] = await Item.load(id))
},
clearCollectionLink() {
this.collectionLink = null
@@ -29,23 +29,24 @@ export const useItemStore = defineStore('ItemStore', {
if (this.collectionLink) {
return this.collectionLink
} else {
- const response = await axios
+ const response = (await axios
.post('/api/collections', {
items: [...interactionStore.viewedItemIds],
})
.catch((err) => {
console.log(err)
- })
+ })) as any
const collectionLink = response.data.url
this.collectionLink = collectionLink
return collectionLink
}
},
- async fetch(collectionId: string) {
+ async fetch() {
this.clearCollectionLink()
this.items = {}
// todo
// this.viewedIds = (await axios.get(`/api/collections/${collectionId}`)).data
},
},
+ persist: true,
})
diff --git a/src/stores/LocaleStore.ts b/src/stores/LocaleStore.ts
index 8d7c7ac..324747d 100644
--- a/src/stores/LocaleStore.ts
+++ b/src/stores/LocaleStore.ts
@@ -1,4 +1,3 @@
-import { useStorage } from '@vueuse/core'
import { defineStore } from 'pinia'
const getBrowserLocale = () => {
@@ -14,6 +13,7 @@ const getBrowserLocale = () => {
export const useLocaleStore = defineStore('LocaleStore', {
state: () => ({
- locale: useStorage('locale', getBrowserLocale()),
+ locale: getBrowserLocale(),
}),
+ persist: true,
})
diff --git a/src/stores/PlaceStore.ts b/src/stores/PlaceStore.ts
index de5facf..98859b8 100644
--- a/src/stores/PlaceStore.ts
+++ b/src/stores/PlaceStore.ts
@@ -1,10 +1,10 @@
import { defineStore } from 'pinia'
-import axios from 'axios'
-import { useStorage } from '@vueuse/core'
+
+import Place from '@/models/Place'
export const usePlaceStore = defineStore('PlaceStore', {
state: () => ({
- places: useStorage('places', {}),
+ places: {} as Record,
}),
actions: {
get(id: string) {
@@ -13,11 +13,11 @@ export const usePlaceStore = defineStore('PlaceStore', {
}
},
async load(id: string) {
- const response = await axios.get(`/api/places/${id}`)
- return (this.places[id] = response.data.data)
+ return (this.places[id] = await Place.load(id))
},
clearCache() {
this.places = {}
},
},
+ persist: true,
})
diff --git a/src/stores/SectionStore.ts b/src/stores/SectionStore.ts
index 0900bc8..9a29280 100644
--- a/src/stores/SectionStore.ts
+++ b/src/stores/SectionStore.ts
@@ -1,10 +1,11 @@
import { defineStore } from 'pinia'
import axios from 'axios'
-import { useStorage } from '@vueuse/core'
+
+import Section from '@/models/Section'
export const useSectionStore = defineStore('SectionStore', {
state: () => ({
- sections: useStorage('sections', {}),
+ sections: {} as Record,
}),
actions: {
get(id: string) {
@@ -13,11 +14,11 @@ export const useSectionStore = defineStore('SectionStore', {
}
},
async load(id: string) {
- const response = await axios.get(`/api/sections/${id}`)
- return (this.sections[id] = response.data.data)
+ return (this.sections[id] = await Section.load(id))
},
clearCache() {
this.sections = {}
},
},
+ persist: true,
})
diff --git a/src/stores/StoryStore.ts b/src/stores/StoryStore.ts
index d32bcb9..9c8764a 100644
--- a/src/stores/StoryStore.ts
+++ b/src/stores/StoryStore.ts
@@ -1,11 +1,12 @@
import { defineStore } from 'pinia'
-import axios from 'axios'
-import { useStorage } from '@vueuse/core'
+
+import Story from '@/models/Story'
export const useStoryStore = defineStore('StoryStore', {
state: () => ({
- stories: useStorage('stories', {}),
+ stories: {} as Record,
}),
+
actions: {
get(id: string) {
if (id in this.stories) {
@@ -13,11 +14,11 @@ export const useStoryStore = defineStore('StoryStore', {
}
},
async load(id: string) {
- const response = await axios.get(`/api/stories/${id}`)
- return (this.stories[id] = response.data.data)
+ return (this.stories[id] = await Story.load(id))
},
clearCache() {
this.stories = {}
},
},
+ persist: true,
})