Skip to content

Commit 74bb329

Browse files
authored
Example implementation of API-Requests in frontend (#8)
* Example implementation of API-Requests in frontend * Remove invalid package.json dependency
1 parent cae1705 commit 74bb329

18 files changed

Lines changed: 183 additions & 315 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.idea/
22
.vscode/
3+
__pycache__/
34

45
*.env

backend/app/main.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from contextlib import asynccontextmanager
55

66
from fastapi import FastAPI
7+
from starlette.middleware.cors import CORSMiddleware
78

89
from app.core.config import settings
910
from app.core.database import init_db
@@ -48,6 +49,23 @@ async def lifespan(_app: FastAPI):
4849
)
4950

5051

52+
# ---------------------------------------------------------
53+
# Development-only CORS configuration
54+
# ---------------------------------------------------------
55+
if settings.ENVIRONMENT == "dev":
56+
logger.info("🌐 Enabling CORS for local development...")
57+
app.add_middleware(
58+
CORSMiddleware,
59+
allow_origins=[
60+
"http://localhost:5173",
61+
"http://127.0.0.1:5173",
62+
],
63+
allow_credentials=True,
64+
allow_methods=["*"],
65+
allow_headers=["*"],
66+
)
67+
68+
5169
# ---------------------------------------------------------
5270
# Register Routers
5371
# ---------------------------------------------------------

backend/requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ httpx==0.28.1
1717
email-validator==2.3.0
1818

1919
# --- Security & Auth ---
20-
python-jose[cryptography]==3.3.0
20+
python-jose[cryptography]==3.3.0
21+
starlette~=0.49.3

frontend/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,12 @@
1212
"preview": "vite preview"
1313
},
1414
"dependencies": {
15+
"axios": "^1.13.1",
1516
"vue": "^3.5.22",
16-
"vuetify": "^3.10.7"
17+
"vue-router": "^4.6.3",
18+
"vuetify": "^3.10.7",
19+
"tailwindcss": "^4.1.16",
20+
"pinia": "^3.0.3"
1721
},
1822
"devDependencies": {
1923
"@vitejs/plugin-vue": "^6.0.1",

frontend/src/App.vue

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,12 @@
11
<script setup>
2-
import HelloWorld from './components/HelloWorld.vue'
3-
import TheWelcome from './components/TheWelcome.vue'
42
</script>
53

64
<template>
7-
<header>
8-
<img alt="Vue logo" class="logo" src="./assets/logo.svg" width="125" height="125" />
9-
10-
<div class="wrapper">
11-
<HelloWorld msg="You did it!" />
12-
</div>
13-
</header>
14-
155
<main>
16-
<TheWelcome />
6+
<router-view />
177
</main>
188
</template>
199

2010
<style scoped>
21-
header {
22-
line-height: 1.5;
23-
}
24-
25-
.logo {
26-
display: block;
27-
margin: 0 auto 2rem;
28-
}
29-
30-
@media (min-width: 1024px) {
31-
header {
32-
display: flex;
33-
place-items: center;
34-
padding-right: calc(var(--section-gap) / 2);
35-
}
36-
37-
.logo {
38-
margin: 0 2rem 0 0;
39-
}
4011
41-
header .wrapper {
42-
display: flex;
43-
place-items: flex-start;
44-
flex-wrap: wrap;
45-
}
46-
}
47-
</style>
12+
</style>

frontend/src/components/HelloWorld.vue

Lines changed: 0 additions & 44 deletions
This file was deleted.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script setup>
2+
import {useAuthStore} from "@/stores/auth.js";
3+
4+
const authStore = useAuthStore()
5+
6+
</script>
7+
8+
<template>
9+
<h1>Hello, {{ authStore.user }}</h1>
10+
<p>{{ authStore.accessToken }}</p>
11+
</template>
12+
13+
<style scoped>
14+
15+
</style>
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<script setup>
2+
import { ref } from 'vue';
3+
import axios from 'axios';
4+
import { useRouter } from 'vue-router';
5+
import { useAuthStore } from '@/stores/auth';
6+
7+
const username = ref('michael');
8+
const errorMessage = ref(null);
9+
const isLoading = ref(false);
10+
11+
const authStore = useAuthStore();
12+
const router = useRouter();
13+
14+
const handleLogin = async () => {
15+
isLoading.value = true;
16+
errorMessage.value = null;
17+
18+
try {
19+
console.log("Trying to login")
20+
const response = await axios.post('http://localhost:8000/auth/login', {
21+
username: username.value,
22+
});
23+
console.log(response)
24+
25+
const { access_token, refresh_token, user } = response.data;
26+
27+
authStore.setAuth({
28+
accessToken: access_token,
29+
refreshToken: refresh_token,
30+
user,
31+
});
32+
33+
console.log(authStore.accessToken);
34+
35+
await router.push({ name: 'home' });
36+
37+
} catch (error) {
38+
if (error.response?.data?.detail) {
39+
errorMessage.value = error.response.data.detail;
40+
} else {
41+
errorMessage.value = 'An unexpected error occurred.';
42+
}
43+
console.error('Login failed:', error);
44+
} finally {
45+
isLoading.value = false;
46+
}
47+
};
48+
</script>
49+
50+
<template>
51+
<div>
52+
<v-btn @click="handleLogin" :disabled="isLoading || authStore.isAuthenticated">
53+
{{ isLoading ? 'Logging in...' : 'Login' }}
54+
</v-btn>
55+
</div>
56+
</template>

frontend/src/components/TheWelcome.vue

Lines changed: 0 additions & 95 deletions
This file was deleted.

0 commit comments

Comments
 (0)