Skip to content

Commit b52b395

Browse files
GalacticCodeGambitEdenBernhardNicoolausPrussianBarondependabot[bot]
authored
Blatt8 (#83)
* Backend First Structure * Backend First Structure * Klassendiagramm * Klassendiagramm.png neu hinzugefügt damit Hintergrund nicht mehr schwarz. * Hello World mäßiger Prototyp für LazyCook * Funktionierende Homepage * Delete old Files * Delete old Files * Delete chart.tsx and new dependencies * Erste Datenbank Funktionen implementiert * Popup-Windows for Signin and Signup * Popup-Windows for Signin and Signup * Bump js-yaml (#79) Bumps the npm_and_yarn group with 1 update in the /Project/Frontend directory: [js-yaml](https://github.com/nodeca/js-yaml). Updates `js-yaml` from 4.1.0 to 4.1.1 - [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md) - [Commits](nodeca/js-yaml@4.1.0...4.1.1) --- updated-dependencies: - dependency-name: js-yaml dependency-version: 4.1.1 dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Backend Signin and Signup functionality * Backend Signin and Signup functionality * Backend Signin and Signup functionality addition * ADR hinzugefügt * Change title from 'Architekturentscheidungen' to 'Architekturstil' Updated the title of the document to reflect the focus on architectural style. * Qualitätsszenario.png und Qualitätsbaum hinzugefügt unter Qualitätsmerkmale * Fix typos in ADR documents * Uncomment permissions section in CI workflow --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Eden Bernhard <etbernhard4@gmail.com> Co-authored-by: Eden Tabea Bernhard <105359952+EdenBernhard@users.noreply.github.com> Co-authored-by: nicla <niclas.matzke@gmail.com> Co-authored-by: PrussianBaron <goebelsamuel@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1 parent f1de713 commit b52b395

19 files changed

Lines changed: 519 additions & 94 deletions

File tree

.github/workflows/ci.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
name: ci
22
on: push
3+
permissions:
4+
contents: read
35

46
jobs:
57
Test:
@@ -44,4 +46,4 @@ jobs:
4446
exit 1
4547
4648
- name: Smoke test
47-
run: curl -fsSL -o /dev/null http://localhost:8000/
49+
run: curl -fsSL -o /dev/null http://localhost:8000/

.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Project/Dockerfile-backend

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ ENV PYTHONUNBUFFERED=1
1414

1515
#EXPOSE 3000
1616

17-
CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:3000", "--workers", "4", "main:app"]
17+
CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:3000", "--workers", "4", "LazyCookVerwaltung:app"]

Project/Frontend/app/homepage/signin.tsx

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, {useState} from 'react';
22
import {AlertCircle, CheckCircle, ChefHat, Mail, X, Lock} from 'lucide-react';
33
import {Button} from "@/app/components/ui/button";
44
import "./popup.css"
5-
5+
import { useRouter } from 'next/navigation';
66

77
interface AnmeldenProps {
88
isOpen: boolean;
@@ -11,6 +11,8 @@ interface AnmeldenProps {
1111
}
1212

1313
export function Anmelden({ isOpen, onClose, onSwitchToRegister }: AnmeldenProps) {
14+
const router = useRouter();
15+
1416
const [formData, setFormData] = useState({
1517
email: '',
1618
password: '',
@@ -24,7 +26,7 @@ export function Anmelden({ isOpen, onClose, onSwitchToRegister }: AnmeldenProps)
2426
email: false,
2527
password: false,
2628
});
27-
const [submitted, setSubmitted] = useState(false);
29+
const [message, setMessage] = useState('');
2830

2931
const validateEmail = (email: string) => {
3032
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
@@ -93,7 +95,7 @@ export function Anmelden({ isOpen, onClose, onSwitchToRegister }: AnmeldenProps)
9395
setErrors(newErrors);
9496
};
9597

96-
const handleSubmit = () => {
98+
const handleSubmit = async () => {
9799
// Alle Felder als berührt markieren
98100
setTouched({
99101
email: true,
@@ -104,20 +106,37 @@ export function Anmelden({ isOpen, onClose, onSwitchToRegister }: AnmeldenProps)
104106
setErrors(newErrors);
105107

106108
if (!newErrors.email && !newErrors.password) {
107-
// Hier würdest du normalerweise die API aufrufen
108109
console.log('Formular erfolgreich validiert:', formData);
109-
setSubmitted(true);
110-
111-
// Formular zurücksetzen nach 2 Sekunden
112-
setTimeout(() => {
113-
setFormData({
114-
email: '',
115-
password: '',
110+
try {
111+
const response = await fetch('http://localhost:3000/api/login', {
112+
method: 'POST',
113+
headers: {
114+
'Content-Type': 'application/json',
115+
},
116+
body: JSON.stringify(formData),
116117
});
117-
setTouched({email: false, password: false});
118-
setSubmitted(false);
119-
onClose()
120-
}, 2000);
118+
119+
const data = await response.json();
120+
121+
122+
if (response.ok && data.message.includes('erfolgreich')) {
123+
setMessage(data.message || 'Anmeldung erfolgreich');
124+
setFormData({ email: '', password: ''});
125+
126+
setTouched({email: false, password: false});
127+
onClose();
128+
setMessage('');
129+
router.push('/recipeFinder');
130+
131+
} else {
132+
// Fehler vom Backend (Status 400-599)
133+
setMessage(data.detail || data.message || 'Anmeldung fehlgeschlagen');
134+
}
135+
} catch (error) {
136+
// Netzwerkfehler
137+
setMessage('Netzwerkfehler: Backend nicht erreichbar');
138+
console.error('Error:', error);
139+
}
121140
}
122141
};
123142

@@ -154,10 +173,13 @@ export function Anmelden({ isOpen, onClose, onSwitchToRegister }: AnmeldenProps)
154173
</p>
155174
</div>
156175

157-
{submitted && (
158-
<div className="mb-6 p-4 bg-green-50 border border-green-200 rounded-lg flex items-center gap-3">
159-
<CheckCircle className="text-green-600" size={20} />
160-
<span className="text-green-800 font-medium">Erfolgreich angemeldet!</span>
176+
{message && (
177+
<div className={`mt-4 p-3 rounded-md ${
178+
message.includes('erfolgreich')
179+
? 'bg-green-100 text-green-700'
180+
: 'bg-red-100 text-red-700'
181+
}`}>
182+
{message}
161183
</div>
162184
)}
163185

Project/Frontend/app/homepage/signup.tsx

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@ import {Button} from "@/app/components/ui/button";
44
import "./popup.css"
55

66

7+
78
interface RegistrierenProps {
89
isOpen: boolean;
910
onClose: () => void;
1011
onSwitchToLogin: () => void;
1112
}
1213

1314
export function Registrieren({ isOpen, onClose, onSwitchToLogin }: RegistrierenProps) {
15+
16+
1417
const [formData, setFormData] = useState({
1518
email: '',
1619
password: '',
@@ -27,7 +30,7 @@ export function Registrieren({ isOpen, onClose, onSwitchToLogin }: RegistrierenP
2730
password: false,
2831
confirmPassword: false
2932
});
30-
const [submitted, setSubmitted] = useState(false);
33+
const [message, setMessage] = useState('');
3134

3235
const validateEmail = (email: string) => {
3336
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
@@ -103,7 +106,7 @@ export function Registrieren({ isOpen, onClose, onSwitchToLogin }: RegistrierenP
103106
setErrors(newErrors);
104107
};
105108

106-
const handleSubmit = () => {
109+
const handleSubmit = async () => {
107110
// Alle Felder als berührt markieren
108111
setTouched({
109112
email: true,
@@ -116,21 +119,38 @@ export function Registrieren({ isOpen, onClose, onSwitchToLogin }: RegistrierenP
116119

117120
if (!newErrors.email && !newErrors.password && !newErrors.confirmPassword) {
118121
console.log('Formular erfolgreich validiert:', formData);
119-
setSubmitted(true);
120122

121-
// Hier würdest du normalerweise deine API aufrufen
122-
// Nach erfolgreicher API-Antwort kannst du das Modal schließen
123-
124-
setTimeout(() => {
125-
setFormData({
126-
email: '',
127-
password: '',
128-
confirmPassword: ''
123+
try {
124+
const response = await fetch('http://localhost:3000/api/register', {
125+
method: 'POST',
126+
headers: {
127+
'Content-Type': 'application/json',
128+
},
129+
body: JSON.stringify(formData),
129130
});
130-
setTouched({confirmPassword: false, email: false, password: false});
131-
setSubmitted(false);
132-
onClose()
133-
}, 2000);
131+
132+
const data = await response.json();
133+
134+
135+
if (response.ok && data.message.includes('erfolgreich')) {
136+
// Erfolg (Status 200-299)
137+
setMessage(data.message || 'Registrierung erfolgreich');
138+
setFormData({ email: '', password: '', confirmPassword: '' });
139+
140+
setTimeout(() => {
141+
setTouched({confirmPassword: false, email: false, password: false});
142+
onClose();
143+
setMessage('');
144+
}, 2000);
145+
} else {
146+
// Fehler vom Backend (Status 400-599)
147+
setMessage(data.detail || data.message || 'Registrierung fehlgeschlagen');
148+
}
149+
} catch (error) {
150+
// Netzwerkfehler
151+
setMessage('Netzwerkfehler: Backend nicht erreichbar');
152+
console.error('Error:', error);
153+
}
134154
}
135155
};
136156

@@ -168,10 +188,13 @@ export function Registrieren({ isOpen, onClose, onSwitchToLogin }: RegistrierenP
168188
</p>
169189
</div>
170190

171-
{submitted && (
172-
<div className="mb-6 p-4 bg-green-50 border border-green-200 rounded-lg flex items-center gap-3">
173-
<CheckCircle className="text-green-600" size={20} />
174-
<span className="text-green-800 font-medium">Erfolgreich registriert!</span>
191+
{message && (
192+
<div className={`mt-4 p-3 rounded-md ${
193+
message.includes('erfolgreich')
194+
? 'bg-green-100 text-green-700'
195+
: 'bg-red-100 text-red-700'
196+
}`}>
197+
{message}
175198
</div>
176199
)}
177200

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
'use client';
2+
3+
import { useState } from 'react';
4+
5+
export default function RecipeFinder() {
6+
const [search, setSearch] = useState('');
7+
8+
return (
9+
<div className="max-w-6xl mx-auto p-8">
10+
<h1 className="text-4xl font-bold mb-8 text-center">
11+
Recipe Finder
12+
</h1>
13+
14+
<div className="mb-8">
15+
<input
16+
type="text"
17+
placeholder="Suche nach Rezepten..."
18+
value={search}
19+
onChange={(e) => setSearch(e.target.value)}
20+
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
21+
/>
22+
</div>
23+
</div>
24+
);
25+
26+
}

0 commit comments

Comments
 (0)