Compare commits
4 Commits
debian12
...
debian12ne
Author | SHA1 | Date | |
---|---|---|---|
e3e2746cec | |||
1db7b9da80 | |||
e1ac9db05c | |||
7f74a740ae |
@@ -118,7 +118,7 @@ app.post("/api/updateUser", authenticate, async (req, res) => {
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Express backend server is running at http://localhost:${port}`);
|
||||
console.log(`Express backend server is running at Port: ${port}`);
|
||||
});
|
||||
|
||||
// error handling code
|
||||
|
@@ -1,33 +1,42 @@
|
||||
services:
|
||||
# admin_react-frontend:
|
||||
# container_name: bikelane-frontend_react-admin
|
||||
# build: ./frontend_admin
|
||||
# ports:
|
||||
# - "5001:5001"
|
||||
# environment:
|
||||
# - CHOKIDAR_USEPOLLING=true
|
||||
# volumes:
|
||||
# - ./frontend_admin:/app
|
||||
# - /app/node_modules
|
||||
# restart: unless-stopped
|
||||
admin_react-frontend:
|
||||
container_name: bikelane-frontend_react-admin
|
||||
build: ./frontend_admin
|
||||
ports:
|
||||
- "5001:5001"
|
||||
networks:
|
||||
- proxynet
|
||||
- bikelane_network
|
||||
environment:
|
||||
- CHOKIDAR_USEPOLLING=true
|
||||
volumes:
|
||||
- ./frontend_admin:/app
|
||||
- /app/node_modules
|
||||
restart: unless-stopped
|
||||
|
||||
# user_react-frontend:
|
||||
# container_name: bikelane-frontend_react-user
|
||||
# build: ./frontend_user
|
||||
# ports:
|
||||
# - "5003:5003"
|
||||
# environment:
|
||||
# - CHOKIDAR_USEPOLLING=true
|
||||
# volumes:
|
||||
# - ./frontend_user:/app
|
||||
# - /app/node_modules
|
||||
# restart: unless-stopped
|
||||
user_react-frontend:
|
||||
container_name: bikelane-frontend_react-user
|
||||
build: ./frontend_user
|
||||
networks:
|
||||
- proxynet
|
||||
- bikelane_network
|
||||
ports:
|
||||
- "5003:5003"
|
||||
environment:
|
||||
- CHOKIDAR_USEPOLLING=true
|
||||
volumes:
|
||||
- ./frontend_user:/app
|
||||
- /app/node_modules
|
||||
restart: unless-stopped
|
||||
|
||||
bikelane-backend:
|
||||
container_name: bikelane-backend_express
|
||||
build: ./backend
|
||||
ports:
|
||||
- "5002:5002"
|
||||
networks:
|
||||
- proxynet
|
||||
- bikelane_network
|
||||
environment:
|
||||
DB_HOST: mysql
|
||||
DB_USER: root
|
||||
@@ -43,6 +52,8 @@ services:
|
||||
container_name: bikelane-mysql
|
||||
image: mysql:8.0
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- bikelane_network
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: D7Ze0lwV9hMrNQHdz1Q8yi0MIQuOO8
|
||||
MYSQL_DATABASE: bikelane
|
||||
@@ -53,3 +64,9 @@ services:
|
||||
|
||||
volumes:
|
||||
mysql-data:
|
||||
|
||||
networks:
|
||||
proxynet:
|
||||
external: true
|
||||
bikelane_network:
|
||||
external: false
|
||||
|
@@ -1,12 +1,13 @@
|
||||
FROM node:20-alpine
|
||||
|
||||
# Build Stage
|
||||
FROM node:20-alpine AS build
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
# Production Stage
|
||||
FROM nginx:stable-alpine AS production
|
||||
COPY --from=build /app/build /usr/share/nginx/html
|
||||
EXPOSE 5001
|
||||
|
||||
CMD ["npm", "start"]
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
|
@@ -1,67 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import "./App.css";
|
||||
import Header from "./Header";
|
||||
|
||||
function App() {
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
try {
|
||||
const response = await fetch("http://localhost:5002/api/login", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
username,
|
||||
password,
|
||||
}),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
console.log("Login successful");
|
||||
// Handle successful login here
|
||||
} else {
|
||||
console.log("Login failed");
|
||||
// Handle login error here
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Login error:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div>
|
||||
<label htmlFor="username">Username:</label>
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
name="username"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="password">Password:</label>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
@@ -1,30 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import Header from "./components/Header";
|
||||
import LoginCard from "./components/LoginCard";
|
||||
|
||||
function App() {
|
||||
const [showLogin, setShowLogin] = useState(false);
|
||||
|
||||
const handleLoginClick = () => setShowLogin(true);
|
||||
const handleCloseLogin = () => setShowLogin(false);
|
||||
|
||||
const handleLoginSubmit = (username: string, password: string) => {
|
||||
// Hier kannst du fetch einbauen
|
||||
alert(`Login: ${username} / ${password}`);
|
||||
setShowLogin(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-white">
|
||||
<Header onLoginClick={handleLoginClick} />
|
||||
<main className="pt-20 w-full h-full flex flex-col items-center justify-start">
|
||||
{/* Hier kommt später der Seiteninhalt */}
|
||||
{showLogin && (
|
||||
<LoginCard onClose={handleCloseLogin} onSubmit={handleLoginSubmit} />
|
||||
)}
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
@@ -1,29 +0,0 @@
|
||||
import React from "react";
|
||||
import bike from "../../src/assets/bicycle-solid.svg";
|
||||
import user from "../../src/assets/circle-user-solid.svg";
|
||||
|
||||
type HeaderProps = {
|
||||
onLoginClick: () => void;
|
||||
};
|
||||
|
||||
const Header: React.FC<HeaderProps> = ({ onLoginClick }) => (
|
||||
<header className="fixed top-0 left-0 w-full h-20 bg-[#101c5e] flex items-center justify-between px-10 z-50 shadow">
|
||||
<div className="flex items-center gap-3">
|
||||
<img src={bike} alt="Bike Logo" className="h-10 w-10" />
|
||||
<span className="text-white text-2xl font-semibold select-none">
|
||||
Bikelane <b>Web</b>
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<img src={user} alt="User Icon" className="h-8 w-8" />
|
||||
<button
|
||||
onClick={onLoginClick}
|
||||
className="bg-white text-[#101c5e] font-bold px-5 py-1 rounded-lg text-lg border-2 border-white hover:bg-gray-200 transition"
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
|
||||
export default Header;
|
@@ -1,72 +0,0 @@
|
||||
import React, { useRef, useEffect } from "react";
|
||||
|
||||
type LoginCardProps = {
|
||||
onClose: () => void;
|
||||
onSubmit: (username: string, password: string) => void;
|
||||
};
|
||||
|
||||
const LoginCard: React.FC<LoginCardProps> = ({ onClose, onSubmit }) => {
|
||||
const [username, setUsername] = React.useState("");
|
||||
const [password, setPassword] = React.useState("");
|
||||
const cardRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const handler = (e: MouseEvent) => {
|
||||
if (cardRef.current && !cardRef.current.contains(e.target as Node)) {
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
document.addEventListener("mousedown", handler);
|
||||
return () => document.removeEventListener("mousedown", handler);
|
||||
}, [onClose]);
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 bg-black bg-opacity-30 flex items-center justify-center z-40">
|
||||
<div
|
||||
ref={cardRef}
|
||||
className="bg-gray-200 rounded-xl shadow-lg w-full max-w-md flex flex-col"
|
||||
>
|
||||
<div className="bg-[#101c5e] text-white rounded-t-xl px-8 py-4 text-center text-2xl font-bold">
|
||||
Login
|
||||
</div>
|
||||
<form
|
||||
className="flex flex-col gap-5 px-8 py-6"
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
onSubmit(username, password);
|
||||
}}
|
||||
>
|
||||
<label className="font-bold">
|
||||
username
|
||||
<input
|
||||
type="text"
|
||||
className="mt-2 w-full rounded-full px-5 py-2 bg-gray-400 outline-none"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
autoFocus
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<label className="font-bold">
|
||||
password
|
||||
<input
|
||||
type="password"
|
||||
className="mt-2 w-full rounded-full px-5 py-2 bg-gray-400 outline-none"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<button
|
||||
type="submit"
|
||||
className="bg-[#101c5e] text-white font-bold rounded-lg py-3 mt-6 text-xl hover:bg-[#203080] transition"
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoginCard;
|
@@ -16,7 +16,7 @@ function App() {
|
||||
const [isAuthenticated, setIsAuthenticated] = useState(
|
||||
!!Cookies.get("token")
|
||||
);
|
||||
const [showLogin, setShowLogin] = useState(false);
|
||||
const [, setShowLogin] = useState(false);
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={{ isAuthenticated, setIsAuthenticated }}>
|
||||
|
@@ -18,7 +18,7 @@ const LoginCard: React.FC<LoginCardProps> = ({ onClose, changeAuth }) => {
|
||||
e.preventDefault();
|
||||
setError("");
|
||||
try {
|
||||
const response = await fetch("http://localhost:5002/api/login", {
|
||||
const response = await fetch("http://45.133.75.67:5002/api/login", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ username, password }),
|
||||
|
@@ -33,7 +33,7 @@ export function useUsers(): UserReturn {
|
||||
|
||||
const fetchUsers = async () => {
|
||||
try {
|
||||
const response = await fetch("http://localhost:5002/api/getAllUsers", {
|
||||
const response = await fetch("http://45.133.75.67:5002/api/getAllUsers", {
|
||||
method: "GET",
|
||||
headers: headers,
|
||||
});
|
||||
@@ -50,7 +50,7 @@ export function useUsers(): UserReturn {
|
||||
};
|
||||
|
||||
const deleteUser = (id: number) => {
|
||||
fetch("http://localhost:5002/api/deleteUser", {
|
||||
fetch("http://45.133.75.67:5002/api/deleteUser", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ id: id }),
|
||||
headers: {
|
||||
@@ -109,7 +109,7 @@ export function useUsers(): UserReturn {
|
||||
console.log("Sending user data:", userData);
|
||||
|
||||
try {
|
||||
const response = await fetch("http://localhost:5002/api/updateUser", {
|
||||
const response = await fetch("http://45.133.75.67:5002/api/updateUser", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(userData),
|
||||
headers: {
|
||||
|
@@ -6,7 +6,7 @@ export const loginUser = async (
|
||||
password: string
|
||||
): Promise<boolean> => {
|
||||
try {
|
||||
const response = await fetch("http://localhost:5002/api/login", {
|
||||
const response = await fetch("http://45.133.75.67:5002/api/login", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ username, password }),
|
||||
@@ -31,7 +31,7 @@ export const logout = () => {
|
||||
};
|
||||
|
||||
export const deleteUser = (id: number) => {
|
||||
fetch("http://localhost:5002/api/deleteUser", {
|
||||
fetch("http://45.133.75.67:5002/api/deleteUser", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ id: id }),
|
||||
headers: {
|
||||
@@ -53,7 +53,7 @@ export const deleteUser = (id: number) => {
|
||||
|
||||
export const replaceUsers = async () => {
|
||||
localStorage.removeItem("users");
|
||||
await fetch("http://localhost:5002/api/getAllUsers", {
|
||||
await fetch("http://45.133.75.67:5002/api/getAllUsers", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${Cookies.get("token")}`,
|
||||
@@ -104,7 +104,7 @@ export const updateUserFunc = async (userID: number) => {
|
||||
console.log("Sending user data:", userData);
|
||||
|
||||
try {
|
||||
const response = await fetch("http://localhost:5002/api/updateUser", {
|
||||
const response = await fetch("http://45.133.75.67:5002/api/updateUser", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(userData),
|
||||
headers: {
|
||||
|
@@ -1,12 +1,13 @@
|
||||
FROM node:20-alpine
|
||||
|
||||
# Build Stage
|
||||
FROM node:20-alpine AS build
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
# Production Stage
|
||||
FROM nginx:stable-alpine AS production
|
||||
COPY --from=build /app/build /usr/share/nginx/html
|
||||
EXPOSE 5003
|
||||
|
||||
CMD ["npm", "start"]
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
|
Reference in New Issue
Block a user