Add initial setup for Gallus_Pub_v1 with Astro

This commit includes a README detailing the Astro starter kit setup and an autogenerated package-lock.json. The setup uses the minimal Astro template, with dependencies like Astro 5.11.0 installed to kickstart the project.
This commit is contained in:
2025-07-13 21:31:00 +02:00
parent a418286bc6
commit 582313f960
35 changed files with 14007 additions and 0 deletions

37
Gallus_Pub/.gitignore vendored Normal file
View File

@ -0,0 +1,37 @@
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
# dependencies
node_modules/
# Expo
.expo/
dist/
web-build/
expo-env.d.ts
# Native
.kotlin/
*.orig.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision
# Metro
.metro-health-check*
# debug
npm-debug.*
yarn-debug.*
yarn-error.*
# macOS
.DS_Store
*.pem
# local env files
.env*.local
# typescript
*.tsbuildinfo

28
Gallus_Pub/App.tsx Normal file
View File

@ -0,0 +1,28 @@
import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { View } from 'react-native';
import LoginScreen from './src/pages/LoginPage';
import AdminScreen from './src/pages/AdminPage';
import HomeScreen from './src/pages/HomePage';
import ProtectedRoute from './src/components/ProtectedRoute';
import { AuthProvider } from './src/AuthContext';
export default function App() {
return (
<AuthProvider>
<BrowserRouter>
<View style={{ flex: 1 }}>
<Routes>
<Route path="/" element={<HomeScreen />} />
<Route path="/admin/login" element={<LoginScreen />} />
<Route path="/admin" element={
<ProtectedRoute>
<AdminScreen />
</ProtectedRoute>
} />
</Routes>
</View>
</BrowserRouter>
</AuthProvider>
);
}

29
Gallus_Pub/app.json Normal file
View File

@ -0,0 +1,29 @@
{
"expo": {
"name": "Gallus_Pub",
"slug": "Gallus_Pub",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
"newArchEnabled": true,
"splash": {
"image": "./assets/splash-icon.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"ios": {
"supportsTablet": true
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff"
},
"edgeToEdgeEnabled": true
},
"web": {
"favicon": "./assets/favicon.png"
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
Gallus_Pub/assets/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

8
Gallus_Pub/index.ts Normal file
View File

@ -0,0 +1,8 @@
import { registerRootComponent } from 'expo';
import App from './App';
// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
// It also ensures that whether you load the app in Expo Go or in a native build,
// the environment is set up appropriately
registerRootComponent(App);

8417
Gallus_Pub/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

27
Gallus_Pub/package.json Normal file
View File

@ -0,0 +1,27 @@
{
"name": "gallus_pub",
"version": "1.0.0",
"main": "index.ts",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
},
"dependencies": {
"@expo/metro-runtime": "~5.0.4",
"expo": "~53.0.9",
"expo-status-bar": "~2.2.3",
"react": "19.0.0",
"react-native": "0.79.2",
"react-native-web": "^0.20.0",
"react-router-dom": "^7.6.0",
"react-dom": "19.0.0"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@types/react": "~19.0.10",
"typescript": "~5.8.3"
},
"private": true
}

View File

@ -0,0 +1,44 @@
import React, { createContext, useState, useContext, ReactNode } from 'react';
type AuthContextType = {
isAdmin: boolean;
login: (username: string, password: string) => Promise<void>;
logout: () => void;
};
const AuthContext = createContext<AuthContextType | null>(null);
export const AuthProvider = ({ children }: { children: ReactNode }) => {
const [isAdmin, setIsAdmin] = useState(false);
const login = async (username: string, password: string) => {
// Hier würden Sie normalerweise API-Anfragen machen, um die Anmeldedaten zu überprüfen
// Einfache Validierung für das Beispiel:
if (username === 'admin' && password === 'password') {
setIsAdmin(true);
// In einer echten Anwendung würden Sie hier einen Token im localStorage speichern
localStorage.setItem('isAdmin', 'true');
return;
}
throw new Error('Falsche Anmeldedaten');
};
const logout = () => {
setIsAdmin(false);
localStorage.removeItem('isAdmin');
};
return (
<AuthContext.Provider value={{ isAdmin, login, logout }}>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => {
const context = useContext(AuthContext);
if (!context) {
throw new Error('useAuth muss innerhalb eines AuthProviders verwendet werden');
}
return context;
};

View File

@ -0,0 +1,20 @@
import React from 'react';
import { Navigate } from 'react-router-dom';
import { useAuth } from '../AuthContext';
type ProtectedRouteProps = {
children: React.ReactNode;
};
const ProtectedRoute: React.FC<ProtectedRouteProps> = ({ children }) => {
const { isAdmin } = useAuth();
if (!isAdmin) {
// Wenn nicht angemeldet, zur Login-Seite umleiten
return <Navigate to="/admin/login" replace />;
}
return <>{children}</>;
};
export default ProtectedRoute;

View File

@ -0,0 +1,35 @@
import React from 'react';
import { useAuth } from '../AuthContext';
const AdminPage: React.FC = () => {
const { logout } = useAuth();
return (
<div style={styles.container}>
<h1>Admin</h1>
<p>Willkommen im Admin-Bereich! Hier können Sie Ihr Gallus Pub verwalten.</p>
<button onClick={logout} style={styles.button}>Abmelden</button>
</div>
);
};
const styles = {
container: {
maxWidth: '800px',
margin: '50px auto',
padding: '20px',
boxShadow: '0 0 10px rgba(0,0,0,0.1)',
borderRadius: '5px',
},
button: {
padding: '10px',
backgroundColor: '#f44336',
color: 'white',
border: 'none',
borderRadius: '3px',
cursor: 'pointer',
marginTop: '20px',
}
};
export default AdminPage;

View File

@ -0,0 +1,23 @@
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
export default function HomeScreen() {
return (
<View style={styles.container}>
<Text style={styles.title}>Willkommen bei Gallus Pub</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
},
title: {
fontSize: 24,
fontWeight: 'bold',
},
});

View File

@ -0,0 +1,93 @@
import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '../AuthContext';
const LoginPage: React.FC = () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const { login } = useAuth();
const navigate = useNavigate();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setError('');
try {
await login(username, password);
navigate('/admin');
} catch (err) {
setError('Anmeldung fehlgeschlagen. Bitte überprüfen Sie Ihre Anmeldedaten.');
}
};
return (
<div style={styles.container}>
<h2>Admin-Login</h2>
{error && <p style={styles.error}>{error}</p>}
<form onSubmit={handleSubmit} style={styles.form}>
<div style={styles.inputGroup}>
<label htmlFor="username">Benutzername:</label>
<input
type="text"
id="username"
value={username}
onChange={(e) => setUsername(e.target.value)}
style={styles.input}
required
/>
</div>
<div style={styles.inputGroup}>
<label htmlFor="password">Passwort:</label>
<input
type="password"
id="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
style={styles.input}
required
/>
</div>
<button type="submit" style={styles.button}>Anmelden</button>
</form>
</div>
);
};
const styles = {
container: {
maxWidth: '400px',
margin: '100px auto',
padding: '20px',
boxShadow: '0 0 10px rgba(0,0,0,0.1)',
borderRadius: '5px',
},
form: {
display: 'flex',
flexDirection: 'column' as 'column',
},
inputGroup: {
marginBottom: '15px',
},
input: {
width: '100%',
padding: '10px',
borderRadius: '3px',
border: '1px solid #ddd',
marginTop: '5px',
},
button: {
padding: '10px',
backgroundColor: '#4CAF50',
color: 'white',
border: 'none',
borderRadius: '3px',
cursor: 'pointer',
},
error: {
color: 'red',
marginBottom: '15px',
}
};
export default LoginPage;

6
Gallus_Pub/tsconfig.json Normal file
View File

@ -0,0 +1,6 @@
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"strict": true
}
}