.DS_Store
temp
test-dts/tsconfig.tsbuildinfo
+.env
href="https://cdn.jsdelivr.net/npm/@exampledev/new.css@1/new.min.css"
/>
<link rel="stylesheet" href="https://fonts.xz.style/serve/inter.css" />
+ <style>
+ @keyframes spinner {
+ to {
+ transform: rotate(360deg);
+ }
+ }
+
+ .spinner:before {
+ content: '';
+ box-sizing: border-box;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 30px;
+ height: 30px;
+ margin-top: -15px;
+ margin-left: -15px;
+ border-radius: 50%;
+ border: 1px solid #ccc;
+ border-top-color: #07d;
+ animation: spinner 0.6s linear infinite;
+ }
+ </style>
</head>
<body>
<div id="app"></div>
import { ref, toRaw, unref, watch } from 'vue'
import { acceptHMRUpdate, defineStore } from '../../../src'
-import { getRandomJoke, Joke } from '../views/api/jokes'
+import { getRandomJoke, Joke } from '../api/jokes'
import useSWRV from 'swrv'
export const useJokesSetup = defineStore('jokes-swrv-setup', () => {
import { ref, unref } from 'vue'
import { acceptHMRUpdate, defineStore } from '../../../src'
-import { getRandomJoke, Joke } from '../views/api/jokes'
+import { getRandomJoke, Joke } from '../api/jokes'
export const useJokes = defineStore('jokes', {
state: () => ({
import { acceptHMRUpdate, defineStore } from '../../../src'
-import { getRandomJoke, Joke } from '../views/api/jokes'
+import { getRandomJoke, Joke } from '../api/jokes'
import { usePromise } from 'vue-promised'
import { ref, watch } from 'vue'
--- /dev/null
+import useSWRV from 'swrv'
+import { computed, ref } from 'vue'
+import { acceptHMRUpdate, defineStore } from '../../../src'
+import { getNASAPOD } from '../api/nasa'
+
+import LocalStorageCache from 'swrv/dist/cache/adapters/localStorage'
+
+export const useNasaStore = defineStore('nasa-pod-swrv', () => {
+ // can't go past today
+ const today = new Date().toISOString().slice(0, 10)
+
+ // const currentDate = computed<string>({
+ // get: () => image.value?.date || today,
+ // set: (date) => {
+ // // TODO: router push
+ // }
+ // })
+
+ const currentDate = ref(today)
+
+ const {
+ data: image,
+ error,
+ isValidating,
+ } = useSWRV(
+ () => `nasa-pod-${currentDate.value}`,
+ () => getNASAPOD(currentDate.value),
+ {
+ refreshInterval: 0,
+ ttl: 0,
+ revalidateOnFocus: false,
+ cache: new LocalStorageCache(),
+ }
+ )
+
+ function incrementDay(date: string) {
+ const from = new Date(date).getTime()
+
+ currentDate.value = new Date(from + 1000 * 60 * 60 * 24)
+ .toISOString()
+ .slice(0, 10)
+ }
+
+ function decrementDay(date: string) {
+ const from = new Date(date).getTime()
+
+ currentDate.value = new Date(from - 1000 * 60 * 60 * 24)
+ .toISOString()
+ .slice(0, 10)
+ }
+
+ return { image, currentDate, incrementDay, decrementDay, error, isValidating }
+})
+
+if (import.meta.hot) {
+ import.meta.hot.accept(acceptHMRUpdate(useNasaStore, import.meta.hot))
+}
--- /dev/null
+<template>
+ <section>
+ <h2>Nasa Picture of the day</h2>
+
+ <section class="py-4 text-center date-selector">
+ <button @click="decrementDay(currentDate)">Previous Day</button>
+ <p class="inline-block mx-2">
+ <input type="date" v-model="currentDate" />
+ </p>
+ <button
+ @click="incrementDay(currentDate)"
+ :disabled="currentDate >= today"
+ >
+ Next Day
+ </button>
+ </section>
+
+ <template v-if="error">
+ <p>
+ ❌ Error:
+ <br />
+ {{ error }}
+ </p>
+ </template>
+
+ <template v-else-if="isValidating">
+ <div class="spinner"></div>
+ </template>
+
+ <template v-else-if="image">
+ <h3 class="mb-4 text-center">{{ image.title }}</h3>
+
+ <figure class="mb-0">
+ <img
+ class="max-w-full m-auto max-h-[75vh]"
+ :src="image.url"
+ :key="image.url"
+ :alt="image.title"
+ />
+ <figcaption class="mt-2">{{ image.explanation }}</figcaption>
+ </figure>
+ </template>
+
+ <template v-else-if="isValidating">
+ <div class="spinner"></div>
+ </template>
+ </section>
+</template>
+
+<script setup lang="ts">
+import { toRefs } from 'vue'
+import { useNasaStore } from '../stores/nasa'
+
+const nasa = useNasaStore()
+
+const today = new Date().toISOString().slice(0, 10)
+
+const { image, error, currentDate, isValidating } = toRefs(nasa.$state)
+const { incrementDay, decrementDay } = nasa
+</script>
+
+<style scoped>
+.date-selector {
+ padding: 1rem 0;
+ text-align: center;
+}
+
+.date-selector > p {
+ display: inline-block;
+ margin: 0 0.4rem;
+}
+
+button {
+ margin: 0;
+}
+</style>