Added basic view for classroom compliance app.

This commit is contained in:
Andrew Lalis 2024-12-16 22:47:57 -05:00
parent a52e13fe57
commit e7683a5c9d
7 changed files with 83 additions and 3 deletions

View File

@ -2,4 +2,4 @@
# import.meta.env.VITE_MY_VAR, for example.
# All variables must be prefixed with "VITE_" to be exposed to JS code.
VITE_API_AUTH_URL=http://localhost:8080/api/auth
VITE_API_URL=http://localhost:8080/api

View File

@ -17,6 +17,11 @@ const authStore = useAuthStore()
</span>
<button type="button" @click="authStore.logOut" v-if="authStore.state">Log out</button>
</nav>
<nav v-if="authStore.state">
Apps:
<RouterLink to="/classroom-compliance">Classroom Compliance</RouterLink>
</nav>
</div>
</header>

View File

@ -1,3 +1,5 @@
const BASE_URL = import.meta.env.VITE_API_URL + '/auth'
export interface User {
id: number
username: string
@ -6,9 +8,15 @@ export interface User {
isAdmin: boolean
}
export function getAuthHeaders(basicAuth: string) {
return {
Authorization: 'Basic ' + basicAuth,
}
}
export async function login(username: string, password: string): Promise<User | null> {
const basicAuth = btoa(username + ':' + password)
const response = await fetch(import.meta.env.VITE_API_AUTH_URL + '/login', {
const response = await fetch(BASE_URL + '/login', {
method: 'POST',
headers: {
Authorization: 'Basic ' + basicAuth,

View File

@ -0,0 +1,39 @@
import { getAuthHeaders } from '@/api/auth'
const BASE_URL = import.meta.env.VITE_API_URL + '/classroom-compliance'
export interface Class {
id: number
number: number
schoolYear: string
}
export async function createClass(
auth: string,
number: number,
schoolYear: string,
): Promise<Class> {
const response = await fetch(BASE_URL + '/classes', {
method: 'POST',
headers: getAuthHeaders(auth),
body: JSON.stringify({ number: number, schoolYear: schoolYear }),
})
return (await response.json()) as Class
}
export async function getClasses(auth: string): Promise<Class[]> {
const response = await fetch(BASE_URL + '/classes', {
headers: getAuthHeaders(auth),
})
return (await response.json()) as Class[]
}
export async function deleteClass(auth: string, classId: number): Promise<void> {
const response = await fetch(BASE_URL + '/classes/' + classId, {
method: 'DELETE',
headers: getAuthHeaders(auth),
})
if (!response.ok) {
throw new Error('Failed to delete class.')
}
}

View File

@ -13,6 +13,10 @@ const router = createRouter({
path: '/login',
component: LoginView,
},
{
path: '/classroom-compliance',
component: () => import('@/views/apps/ClassroomCompliance.vue'),
},
],
})

View File

@ -19,7 +19,7 @@ export const useAuthStore = defineStore('auth', () => {
state.value = null
}
function getBasicAuth() {
if (!state.value) return null
if (!state.value) throw new Error('User is not authenticated.')
return btoa(state.value.username + ':' + state.value.password)
}
return { state, logIn, logOut, getBasicAuth }

View File

@ -0,0 +1,24 @@
<script setup lang="ts">
import { getClasses, type Class } from '@/api/classroom_compliance';
import { useAuthStore } from '@/stores/auth';
import { onMounted, ref, type Ref } from 'vue';
const classes: Ref<Class[]> = ref([])
const authStore = useAuthStore()
onMounted(async () => {
classes.value = await getClasses(authStore.getBasicAuth())
console.log(classes.value)
})
</script>
<template>
<main>
<h1>Classroom Compliance</h1>
<p>Here you can track stuff.</p>
<div v-for="cls in classes" :key="cls.id">
<h3 v-text="cls.number"></h3>
<p v-text="cls.schoolYear"></p>
</div>
</main>
</template>