initial
This commit is contained in:
commit
72c796c429
21 changed files with 4956 additions and 0 deletions
11
src/App.vue
Normal file
11
src/App.vue
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<script setup>
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<router-link :to="{ name: 'home' }"> Home </router-link>
|
||||
<router-link :to="{ name: 'login' }"> Login </router-link>
|
||||
<hr>
|
||||
<router-view />
|
||||
</template>
|
||||
<style scoped>
|
||||
</style>
|
||||
14
src/main.js
Normal file
14
src/main.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import { setupAuthInterceptor } from '@/services/setupInterceptors.js'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(createPinia())
|
||||
app.use(router)
|
||||
setupAuthInterceptor()
|
||||
|
||||
app.mount('#app')
|
||||
21
src/router/index.js
Normal file
21
src/router/index.js
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import HomeView from '../views/HomeView.vue'
|
||||
import LoginView from '@/views/LoginView.vue'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: HomeView,
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
component: LoginView,
|
||||
}
|
||||
],
|
||||
})
|
||||
|
||||
export default router
|
||||
11
src/services/apiClient.js
Normal file
11
src/services/apiClient.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import axios from 'axios'
|
||||
|
||||
const apiClient = axios.create({
|
||||
baseURL: 'http://localhost:9000/api/v2',
|
||||
timeout: 5000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
})
|
||||
|
||||
export default apiClient
|
||||
12
src/services/setupInterceptors.js
Normal file
12
src/services/setupInterceptors.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import apiClient from '@/services/apiClient'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
|
||||
export function setupAuthInterceptor() {
|
||||
apiClient.interceptors.request.use((config) => {
|
||||
const authStore = useAuthStore()
|
||||
if (authStore.accessToken) {
|
||||
config.headers.Authorization = `Bearer ${authStore.accessToken}`
|
||||
}
|
||||
return config
|
||||
})
|
||||
}
|
||||
41
src/stores/authStore.js
Normal file
41
src/stores/authStore.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import { defineStore } from 'pinia';
|
||||
import { computed, ref } from 'vue';
|
||||
import apiClient from '@/services/apiClient';
|
||||
|
||||
export const useAuthStore = defineStore('auth', () => {
|
||||
// state
|
||||
const accessToken = ref(null)
|
||||
const user = ref(null)
|
||||
|
||||
// getters
|
||||
const isAuthenticated = computed(() => !!accessToken.value)
|
||||
|
||||
// actions
|
||||
const login = async (email, password) => {
|
||||
try {
|
||||
const response = await apiClient.post(
|
||||
"/user/login",
|
||||
{ email, password }
|
||||
)
|
||||
const { access_token } = response.data
|
||||
accessToken.value = access_token
|
||||
|
||||
console.log('Email', email)
|
||||
console.log('Password', password)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
const logout = () => {
|
||||
console.log('logout placeholder')
|
||||
}
|
||||
|
||||
return {
|
||||
accessToken,
|
||||
user,
|
||||
isAuthenticated,
|
||||
login,
|
||||
logout
|
||||
}
|
||||
})
|
||||
12
src/stores/counter.js
Normal file
12
src/stores/counter.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
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 }
|
||||
})
|
||||
7
src/views/HomeView.vue
Normal file
7
src/views/HomeView.vue
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
Home view
|
||||
</template>
|
||||
39
src/views/LoginView.vue
Normal file
39
src/views/LoginView.vue
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<script setup lang="js">
|
||||
import { ref } from 'vue';
|
||||
import { useAuthStore} from '@/stores/authStore.js';
|
||||
|
||||
const store = useAuthStore();
|
||||
|
||||
const email = ref('');
|
||||
const password = ref('');
|
||||
|
||||
|
||||
const onSubmit = () => {
|
||||
store.login(email.value, password.value);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1> Login view </h1>
|
||||
<div>
|
||||
<form @submit.prevent="onSubmit">
|
||||
<div>
|
||||
<label for="email">Email</label>
|
||||
<input type="email" name="email" v-model="email">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="password">Password</label>
|
||||
<input type="password" name="password" v-model="password">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button type="submit">Login</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Loading…
Add table
Add a link
Reference in a new issue