diff --git a/src/composable/parseRouteQuery.ts b/src/composable/parseRouteQuery.ts new file mode 100644 index 0000000..576fd80 --- /dev/null +++ b/src/composable/parseRouteQuery.ts @@ -0,0 +1,13 @@ +import type { LocationQueryValue } from 'vue-router' + +export const parseRouteQuery = (query: LocationQueryValue | LocationQueryValue[]) => { + if (Array.isArray(query)) { + return query.filter((v): v is string => typeof v === 'string') + } else { + return typeof query === 'string' ? [query] : [''] + } +} + +export const parseRedirectQuery = (query: LocationQueryValue | LocationQueryValue[]) => { + return parseRouteQuery(query)[0] || '/' +} diff --git a/src/pages/login/LoginPage.vue b/src/pages/login/LoginPage.vue new file mode 100644 index 0000000..9f1178d --- /dev/null +++ b/src/pages/login/LoginPage.vue @@ -0,0 +1,49 @@ + + + diff --git a/src/pages/membership/MemberShipPageUserTypeSelector.vue b/src/pages/membership/MemberShipPageUserTypeSelector.vue new file mode 100644 index 0000000..d58074f --- /dev/null +++ b/src/pages/membership/MemberShipPageUserTypeSelector.vue @@ -0,0 +1,17 @@ + + + diff --git a/src/pages/membership/MemberShipPageUserTypeSelectorButton.vue b/src/pages/membership/MemberShipPageUserTypeSelectorButton.vue new file mode 100644 index 0000000..377359c --- /dev/null +++ b/src/pages/membership/MemberShipPageUserTypeSelectorButton.vue @@ -0,0 +1,19 @@ + + + diff --git a/src/pages/membership/MembershipPage.vue b/src/pages/membership/MembershipPage.vue index fbb1268..56ff7ca 100644 --- a/src/pages/membership/MembershipPage.vue +++ b/src/pages/membership/MembershipPage.vue @@ -1,5 +1,86 @@ + + diff --git a/src/pages/membership/MembershipPageInputText.vue b/src/pages/membership/MembershipPageInputText.vue new file mode 100644 index 0000000..fc72b17 --- /dev/null +++ b/src/pages/membership/MembershipPageInputText.vue @@ -0,0 +1,34 @@ + + + diff --git a/src/pages/membership/MembershipPageLoginLink.vue b/src/pages/membership/MembershipPageLoginLink.vue new file mode 100644 index 0000000..333abcc --- /dev/null +++ b/src/pages/membership/MembershipPageLoginLink.vue @@ -0,0 +1,13 @@ + + + diff --git a/src/pages/membership/MembershipPageVerifyEmailLink.vue b/src/pages/membership/MembershipPageVerifyEmailLink.vue new file mode 100644 index 0000000..bfd5aa2 --- /dev/null +++ b/src/pages/membership/MembershipPageVerifyEmailLink.vue @@ -0,0 +1,13 @@ + + + diff --git a/src/pages/membership/types/userType.ts b/src/pages/membership/types/userType.ts new file mode 100644 index 0000000..97f6762 --- /dev/null +++ b/src/pages/membership/types/userType.ts @@ -0,0 +1 @@ +export type UserType = 'new' | 'rejoin' | 'active' diff --git a/src/pages/verify-email/VerifyEmailPage.vue b/src/pages/verify-email/VerifyEmailPage.vue new file mode 100644 index 0000000..86bfdd8 --- /dev/null +++ b/src/pages/verify-email/VerifyEmailPage.vue @@ -0,0 +1,52 @@ + + + diff --git a/src/router/index.ts b/src/router/index.ts index 6cedfaa..8172189 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -17,6 +17,16 @@ const router = createRouter({ // which is lazy-loaded when the route is visited. component: () => import('@/pages/membership/MembershipPage.vue'), }, + { + path: '/verify-email', + name: 'verify-email', + component: () => import('@/pages/verify-email/VerifyEmailPage.vue'), + }, + { + path: '/login', + name: 'login', + component: () => import('@/pages/login/LoginPage.vue'), + }, ], }) diff --git a/src/stores/auth.ts b/src/stores/auth.ts new file mode 100644 index 0000000..6797a1d --- /dev/null +++ b/src/stores/auth.ts @@ -0,0 +1,19 @@ +import { defineStore } from 'pinia' +import { computed, readonly, ref } from 'vue' + +export const useAuthStore = defineStore('auth', () => { + const _loggedInTraqId = ref<{ traqId: string } | null>(null) + + const loggedInTraqId = readonly(_loggedInTraqId) + const isLoggedIn = computed(() => _loggedInTraqId.value !== null) + + const login = (traqId: string) => { + _loggedInTraqId.value = { traqId } + } + + const logout = () => { + _loggedInTraqId.value = null + } + + return { isLoggedIn, loggedInTraqId, login, logout } +}) diff --git a/src/stores/counter.ts b/src/stores/counter.ts deleted file mode 100644 index b6757ba..0000000 --- a/src/stores/counter.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ref, computed } from 'vue' -import { defineStore } from 'pinia' - -export const useCounterStore = defineStore('counter', () => { - const count = ref(0) - const doubleCount = computed(() => count.value * 2) - function increment() { - count.value++ - } - - return { count, doubleCount, increment } -}) diff --git a/src/stores/verifiedEmail.ts b/src/stores/verifiedEmail.ts new file mode 100644 index 0000000..27628e5 --- /dev/null +++ b/src/stores/verifiedEmail.ts @@ -0,0 +1,19 @@ +import { defineStore } from 'pinia' +import { computed, readonly, ref } from 'vue' + +export const useVerifiedEmailStore = defineStore('verifiedEmail', () => { + const _verifiedEmail = ref(null) + + const verifiedEmail = readonly(_verifiedEmail) + const hasVerifiedEmail = computed(() => _verifiedEmail.value !== null) + + const setVerifiedEmail = (verifiedEmail: string) => { + _verifiedEmail.value = verifiedEmail + } + + const clearEmail = () => { + _verifiedEmail.value = null + } + + return { verifiedEmail, hasVerifiedEmail, setVerifiedEmail, clearEmail } +})