Commit 2f300868 authored by Patrick Ade's avatar Patrick Ade
Browse files

Refactor authentication and registration processes to use Axios; update API...

Refactor authentication and registration processes to use Axios; update API endpoints and improve error handling
parent 07514b02
...@@ -28,7 +28,7 @@ export const useAuthStore = defineStore('auth', { ...@@ -28,7 +28,7 @@ export const useAuthStore = defineStore('auth', {
actions: { actions: {
async login(username: string, password: string, router: Router | null = null): Promise<void> { async login(username: string, password: string, router: Router | null = null): Promise<void> {
try { try {
const response = await api.post('/auth/login', { const response = await api.post('/login', {
username, username,
password, password,
}) })
...@@ -64,7 +64,7 @@ export const useAuthStore = defineStore('auth', { ...@@ -64,7 +64,7 @@ export const useAuthStore = defineStore('auth', {
} }
try { try {
const response = await api.get('/auth/me') const response = await api.get('/user')
this.user = response.data this.user = response.data
this.isAuthenticated = true this.isAuthenticated = true
} catch (error) { } catch (error) {
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
import { ref } from 'vue' import { ref } from 'vue'
import BauCard from '../components/BauCard.vue' import BauCard from '../components/BauCard.vue'
import RoomCard from '../components/RoomCard.vue' import RoomCard from '../components/RoomCard.vue'
import api from '@/services/apiClient'
const buildings = [ const buildings = [
{ {
...@@ -27,7 +28,7 @@ const buildings = [ ...@@ -27,7 +28,7 @@ const buildings = [
title: 'Bau 8', title: 'Bau 8',
description: 'Informatik und IT-Räume', description: 'Informatik und IT-Räume',
image: new URL('@/assets/bau-8.png', import.meta.url).href, image: new URL('@/assets/bau-8.png', import.meta.url).href,
} },
] ]
const selectedBuildingId = ref<string | null>(null) const selectedBuildingId = ref<string | null>(null)
...@@ -42,16 +43,13 @@ async function loadRooms(buildingId: string) { ...@@ -42,16 +43,13 @@ async function loadRooms(buildingId: string) {
error.value = null error.value = null
try { try {
const response = await fetch(`http://localhost:8000/api/get_rooms_from_building?building=${buildingId}`) const response = await api.get('/get_rooms_from_building', {
const data = await response.json() params: { building: buildingId },
})
if (response.ok) { rooms.value = response.data.rooms
rooms.value = data.rooms
} else {
throw new Error(data.detail || 'Fehler beim Laden der Räume')
}
} catch (err: any) { } catch (err: any) {
error.value = err.message error.value = err.response?.data?.detail || err.message || 'Fehler beim Laden der Räume'
} finally { } finally {
isLoading.value = false isLoading.value = false
} }
...@@ -90,12 +88,14 @@ async function loadRooms(buildingId: string) { ...@@ -90,12 +88,14 @@ async function loadRooms(buildingId: string) {
display: flex; display: flex;
padding: 2rem; padding: 2rem;
gap: 2rem; gap: 2rem;
align-items: flex-start; /* wichtige Ergänzung */ align-items: flex-start;
/* wichtige Ergänzung */
} }
.building-grid { .building-grid {
display: flex; display: flex;
flex-direction: column; /* Gebäude untereinander */ flex-direction: column;
/* Gebäude untereinander */
gap: 1.5rem; gap: 1.5rem;
flex-shrink: 0; flex-shrink: 0;
} }
......
<template>
<div class="chart-view">
<h2>Daten für Raum: {{ room }}</h2>
<div class="time-form">
<label>
Start:
<input class="datetime" type="datetime-local" v-model="start" />
</label>
<label>
Stop:
<input class="datetime" type="datetime-local" v-model="stop" />
</label>
<button @click="loadData">Zeitraum aktualisieren</button>
<button @click="loadDataWithDefaultWindow" class="default-btn">Zeige die letzte Woche</button>
</div>
<div class="chart-grid">
<ChartCard
title="CO₂ Verlauf"
:labels="displayLabels"
:data="co2Data"
borderColor="#ff6384"
/>
<ChartCard
title="Temperatur Verlauf"
:labels="displayLabels"
:data="temperatureData"
borderColor="#36a2eb"
/>
<ChartCard
title="Luftfeuchtigkeit Verlauf"
:labels="displayLabels"
:data="humidityData"
borderColor="#4bc0c0"
/>
</div>
</div>
</template>
<script lang="ts"> <script lang="ts">
import { defineComponent, ref, onMounted, computed } from 'vue' import { defineComponent, ref, onMounted, computed } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import ChartCard from '../components/ChartCard.vue' import ChartCard from '../components/ChartCard.vue'
import api from '@/services/apiClient' // Axios instance
export default defineComponent({ export default defineComponent({
name: 'ChartView', name: 'ChartView',
...@@ -58,16 +19,12 @@ export default defineComponent({ ...@@ -58,16 +19,12 @@ export default defineComponent({
const start = ref('') const start = ref('')
const stop = ref('') const stop = ref('')
// Computed property for displaying max 6 labels
const displayLabels = computed(() => { const displayLabels = computed(() => {
const total = labels.value.length const total = labels.value.length
if (total <= 6) return labels.value if (total <= 6) return labels.value
const result: string[] = [] const result: string[] = Array(total).fill('')
for (let i = 0; i < total; i++) {
result.push('')
}
for (let i = 0; i < 6; i++) { for (let i = 0; i < 6; i++) {
const idx = Math.round(i * (total - 1) / 5) const idx = Math.round((i * (total - 1)) / 5)
result[idx] = labels.value[idx] result[idx] = labels.value[idx]
} }
return result return result
...@@ -85,7 +42,6 @@ export default defineComponent({ ...@@ -85,7 +42,6 @@ export default defineComponent({
const now = new Date() const now = new Date()
const weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000) const weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000)
// Format dates properly for datetime-local inputs
const formatForInput = (date: Date) => { const formatForInput = (date: Date) => {
const year = date.getFullYear() const year = date.getFullYear()
const month = ('0' + (date.getMonth() + 1)).slice(-2) const month = ('0' + (date.getMonth() + 1)).slice(-2)
...@@ -110,16 +66,16 @@ export default defineComponent({ ...@@ -110,16 +66,16 @@ export default defineComponent({
return return
} }
const url = `http://localhost:8000/api/room_data_range?room=${encodeURIComponent(
room
)}&start=${startISO}&stop=${stopISO}`
try { try {
const response = await fetch(url) const response = await api.get('/room_data_range', {
if (!response.ok) throw new Error('Fehler beim Laden') params: {
room,
start: startISO,
stop: stopISO,
},
})
const json = await response.json() const entries = Object.entries(response.data.data).sort(
const entries = Object.entries(json.data).sort(
([a], [b]) => new Date(a).getTime() - new Date(b).getTime() ([a], [b]) => new Date(a).getTime() - new Date(b).getTime()
) )
...@@ -132,18 +88,14 @@ export default defineComponent({ ...@@ -132,18 +88,14 @@ export default defineComponent({
}) })
) )
co2Data.value = entries.map(([, values]: any) => Number(values.co2)) co2Data.value = entries.map(([, values]: any) => Number(values.co2))
temperatureData.value = entries.map(([, values]: any) => temperatureData.value = entries.map(([, values]: any) => Number(values.temperature))
Number(values.temperature) humidityData.value = entries.map(([, values]: any) => Number(values.humidity))
) } catch (err: any) {
humidityData.value = entries.map(([, values]: any) =>
Number(values.humidity)
)
} catch (err) {
console.error('❌ Fehler beim Laden der Daten:', err) console.error('❌ Fehler beim Laden der Daten:', err)
alert('Fehler beim Laden der Daten')
} }
} }
// Function to load data with default last week window
async function loadDataWithDefaultWindow() { async function loadDataWithDefaultWindow() {
setDefaultTimeWindow() setDefaultTimeWindow()
await loadData() await loadData()
...@@ -168,55 +120,3 @@ export default defineComponent({ ...@@ -168,55 +120,3 @@ export default defineComponent({
}, },
}) })
</script> </script>
<style scoped>
.chart-view {
padding: 2rem;
color: #1a1a1a;
}
.time-form {
display: flex;
gap: 1rem;
margin-bottom: 2rem;
align-items: center;
flex-wrap: wrap;
}
.time-form input {
padding: 0.5rem;
font-size: 1rem;
border-radius: 5px;
}
.time-form button {
background: #007bff;
color: white;
padding: 0.6rem 1.2rem;
border: none;
border-radius: 4px;
font-weight: bold;
cursor: pointer;
transition: background-color 0.2s ease;
}
.time-form button:hover {
background-color: #0056b3;
}
.time-form .default-btn {
background: #28a745;
}
.time-form .default-btn:hover {
background-color: #218838;
}
.chart-grid {
display: flex;
flex-wrap: nowrap;
gap: 2rem;
justify-content: flex-start;
flex-direction: row;
}
</style>
<script lang="ts"> <script lang="ts">
import { getCSRFToken } from '../stores/auth' import api from '@/services/apiClient' // Your axios instance
export default { export default {
data() { data() {
...@@ -13,29 +13,23 @@ export default { ...@@ -13,29 +13,23 @@ export default {
methods: { methods: {
async register() { async register() {
try { try {
const response = await fetch('http://localhost:8000/api/register', { const response = await api.post('/register', {
method: 'POST', username: this.email,
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': getCSRFToken(),
},
body: JSON.stringify({
email: this.email,
password: this.password, password: this.password,
}),
credentials: 'include',
}) })
const data = await response.json()
if (response.ok) { if (response.status === 200) {
this.success = 'Registration successful! Please log in.' this.success = 'Registration successful! Please log in.'
setTimeout(() => { setTimeout(() => {
this.$router.push('/login') this.$router.push('/login')
}, 1000) }, 1000)
} else { } else {
this.error = data.error || 'Registration failed' this.error = response.data.error || 'Registration failed'
} }
} catch (err) { } catch (err: any) {
this.error = 'An error occurred during registration: ' + err this.error =
err.response?.data?.error ||
'An error occurred during registration: ' + err.message
} }
}, },
}, },
...@@ -46,7 +40,9 @@ export default { ...@@ -46,7 +40,9 @@ export default {
<div class="register-container"> <div class="register-container">
<div class="register-card"> <div class="register-card">
<h1>Registrieren</h1> <h1>Registrieren</h1>
<p class="intro">Erstelle ein Konto, um Zugriff auf Sensor- und Raumdaten zu erhalten.</p> <p class="intro">
Erstelle ein Konto, um Zugriff auf Sensor- und Raumdaten zu erhalten.
</p>
<form @submit.prevent="register"> <form @submit.prevent="register">
<div class="form-group"> <div class="form-group">
...@@ -80,7 +76,6 @@ export default { ...@@ -80,7 +76,6 @@ export default {
</div> </div>
</template> </template>
<style scoped> <style scoped>
.register-container { .register-container {
display: flex; display: flex;
......
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { getCSRFToken } from '../stores/auth'
import RoomCard from '../components/RoomCard.vue' import RoomCard from '../components/RoomCard.vue'
import api from '@/services/apiClient' // Custom Axios instance
const rooms = ref<string[]>([]) const rooms = ref<string[]>([])
const error = ref<string | null>(null) const error = ref<string | null>(null)
const fetchRooms = async () => { const fetchRooms = async () => {
try { try {
const response = await fetch('http://localhost:8000/api/get_rooms', { const response = await api.get('/get_rooms')
headers: {
'Content-Type': 'application/json', if (response.data.rooms) {
'X-CSRFToken': getCSRFToken(), rooms.value = response.data.rooms
},
credentials: 'include',
})
const data = await response.json()
if (response.ok && data.rooms) {
rooms.value = data.rooms
} else { } else {
error.value = 'Fehler beim Laden der Räume.' error.value = 'Fehler beim Laden der Räume.'
} }
} catch (err) { } catch (err: any) {
error.value = 'Serverfehler: ' + err error.value = err.response?.data?.detail || 'Serverfehler: ' + err.message
} }
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment