From 40c861624047531fa839396562b5b4184d32b64c Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Thu, 13 Feb 2025 06:14:02 +0300 Subject: [PATCH] feat: add cars page --- rsbuild.config.ts | 1 + src/pages/CarsPage.vue | 25 +++++++++++++++++ src/pages/SignIn.vue | 5 +++- src/pages/SignUp.vue | 3 ++ src/router/index.ts | 5 ++++ src/store/auth.ts | 63 +++++++++++++++++++++--------------------- src/store/cars.ts | 25 +++++++++++++++++ src/utils/api.ts | 25 +++++++++++++++++ 8 files changed, 120 insertions(+), 32 deletions(-) create mode 100644 src/pages/CarsPage.vue create mode 100644 src/store/cars.ts create mode 100644 src/utils/api.ts diff --git a/rsbuild.config.ts b/rsbuild.config.ts index 40e044b..0e63ab0 100644 --- a/rsbuild.config.ts +++ b/rsbuild.config.ts @@ -14,6 +14,7 @@ export default defineConfig({ 'process.env.FIREBASE_STORAGE_BUCKET': JSON.stringify(process.env.FIREBASE_STORAGE_BUCKET), 'process.env.FIREBASE_MESSAGING_SENDER_ID': JSON.stringify(process.env.FIREBASE_MESSAGING_SENDER_ID), 'process.env.FIREBASE_APP_ID': JSON.stringify(process.env.FIREBASE_APP_ID), + 'process.env.FIREBASE_DATABASE_URL': JSON.stringify(process.env.FIREBASE_DATABASE_URL), }, }, }); diff --git a/src/pages/CarsPage.vue b/src/pages/CarsPage.vue new file mode 100644 index 0000000..490cfcc --- /dev/null +++ b/src/pages/CarsPage.vue @@ -0,0 +1,25 @@ + + + + diff --git a/src/pages/SignIn.vue b/src/pages/SignIn.vue index 07fe299..23b1dc4 100644 --- a/src/pages/SignIn.vue +++ b/src/pages/SignIn.vue @@ -3,14 +3,17 @@ import { ref } from 'vue'; import { useAuthStore } from '@/store/auth'; import Loader from '@/components/Loader.vue'; + import { useRouter } from 'vue-router'; - const authStore = useAuthStore() + const authStore = useAuthStore(); + const router = useRouter(); const email = ref('') const password = ref('') const signin = async () => { await authStore.auth('signIn',{ email: email.value, password: password.value }) + await router.push('/cars'); } diff --git a/src/pages/SignUp.vue b/src/pages/SignUp.vue index 5b18bd1..58c0f98 100644 --- a/src/pages/SignUp.vue +++ b/src/pages/SignUp.vue @@ -3,14 +3,17 @@ import { ref } from 'vue'; import { useAuthStore } from '@/store/auth'; import Loader from '@/components/Loader.vue'; + import { useRouter } from 'vue-router'; const authStore = useAuthStore() + const router = useRouter(); const email = ref('') const password = ref('') const signup = async () => { await authStore.auth('signUp', { email: email.value, password: password.value }) + await router.push('/cars'); } diff --git a/src/router/index.ts b/src/router/index.ts index f7b7e63..cd29631 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -13,6 +13,11 @@ const router = createRouter({ path: '/sign-in', name: 'SignIn', component: () => import('../pages/SignIn.vue') + }, + { + path: '/cars', + name: 'Cars', + component: () => import('../pages/CarsPage.vue') } ] }) diff --git a/src/store/auth.ts b/src/store/auth.ts index f8e5f02..59cc59b 100644 --- a/src/store/auth.ts +++ b/src/store/auth.ts @@ -52,40 +52,41 @@ export const useAuthStore = defineStore('auth', () => { token: data.idToken, } } catch (e) { - if (!(e instanceof AxiosError)){ + if (e instanceof AxiosError){ + switch (e?.response?.data?.error?.message) { + case 'EMAIL_EXISTS': + error.value = 'Email already exists'; + break; + case 'OPERATION_NOT_ALLOWED': + error.value = 'Operation not allowed'; + break; + case 'TOO_MANY_ATTEMPTS_TRY_LATER': + error.value = 'Too many attempts'; + break; + case 'EMAIL_NOT_FOUND': + error.value = 'Email not found'; + break; + case 'INVALID_LOGIN_CREDENTIALS': + error.value = 'Invalid credentials'; + break; + case 'INVALID_PASSWORD': + error.value = 'Invalid password'; + break; + case 'WEAK_PASSWORD': + error.value = 'Password is weak'; + break; + case 'USER_DISABLED': + error.value = 'User disabled'; + break; + default: + error.value = 'Something went wrong'; + break; + } + } else { error.value = 'Something went wrong'; - return; } - switch (e?.response?.data?.error?.message) { - case 'EMAIL_EXISTS': - error.value = 'Email already exists'; - return; - case 'OPERATION_NOT_ALLOWED': - error.value = 'Operation not allowed'; - return; - case 'TOO_MANY_ATTEMPTS_TRY_LATER': - error.value = 'Too many attempts'; - return; - case 'EMAIL_NOT_FOUND': - error.value = 'Email not found'; - return; - case 'INVALID_LOGIN_CREDENTIALS': - error.value = 'Invalid credentials'; - return; - case 'INVALID_PASSWORD': - error.value = 'Invalid password'; - return; - case 'WEAK_PASSWORD': - error.value = 'Password is weak'; - return; - case 'USER_DISABLED': - error.value = 'User disabled'; - return; - default: - error.value = 'Something went wrong'; - return; - } + throw new Error(error.value); } finally { loading.value = false; } diff --git a/src/store/cars.ts b/src/store/cars.ts new file mode 100644 index 0000000..1765e29 --- /dev/null +++ b/src/store/cars.ts @@ -0,0 +1,25 @@ +import api from '@/utils/api.ts'; +import { defineStore } from 'pinia'; +import { onMounted, ref } from 'vue'; + +export const useCarsStore = defineStore('cars', () => { + const cars = ref([]); + const showLoader = ref(false); + + onMounted(async () => { + try { + showLoader.value = true; + const response = await api.get(`/cars.json`); + cars.value = Object.values(response.data) + } catch (e) { + console.log(e); + } finally { + showLoader.value = false; + } + }); + + return { + cars, + showLoader, + } +}) diff --git a/src/utils/api.ts b/src/utils/api.ts new file mode 100644 index 0000000..531ca7b --- /dev/null +++ b/src/utils/api.ts @@ -0,0 +1,25 @@ +import router from '@/router'; +import { useAuthStore } from '@/store/auth.ts'; +import axios from 'axios'; + +const api = axios.create({ + baseURL: process.env.FIREBASE_DATABASE_URL, +}); + +api.interceptors.request.use((config) => { + const authStore = useAuthStore(); + let params = new URLSearchParams(); + params.append('auth', authStore.userInfo.token); + config.params = params; + + return config +}) + +api.interceptors.response.use(null, (response) => { + if (response.status === 401) { + router.push('/sign-in') + } + return response; +}) + +export default api;