feat: Initialize Flutter app with authentication and scheduling features

- Removed TypeScript configuration file (tsconfig.json).
- Added Flutter plugin dependencies for secure storage.
- Implemented main application structure with routing for login, profile, and schedule screens.
- Developed LoginScreen with authentication logic and user feedback.
- Created ProfileScreen to display user profile information and logout functionality.
- Built ScheduleScreen to show weekly work schedule with navigation controls.
- Integrated AuthService for handling authentication, token storage, and API interactions.
- Updated pubspec.yaml with necessary dependencies for the Flutter project.
This commit is contained in:
2025-08-20 22:48:54 +02:00
parent 925dc6e0c0
commit 871bfcdccb
47 changed files with 629 additions and 13403 deletions

View File

@@ -0,0 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_secure_storage","path":"/Users/benedekballo/.pub-cache/hosted/pub.dev/flutter_secure_storage-8.1.0/","native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"flutter_secure_storage","path":"/Users/benedekballo/.pub-cache/hosted/pub.dev/flutter_secure_storage-8.1.0/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"flutter_secure_storage_macos","path":"/Users/benedekballo/.pub-cache/hosted/pub.dev/flutter_secure_storage_macos-3.1.3/","native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"flutter_secure_storage_linux","path":"/Users/benedekballo/.pub-cache/hosted/pub.dev/flutter_secure_storage_linux-1.2.3/","native_build":true,"dependencies":[],"dev_dependency":false}],"windows":[{"name":"flutter_secure_storage_windows","path":"/Users/benedekballo/.pub-cache/hosted/pub.dev/flutter_secure_storage_windows-2.1.1/","native_build":true,"dependencies":[],"dev_dependency":false}],"web":[{"name":"flutter_secure_storage_web","path":"/Users/benedekballo/.pub-cache/hosted/pub.dev/flutter_secure_storage_web-1.2.1/","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"flutter_secure_storage","dependencies":["flutter_secure_storage_linux","flutter_secure_storage_macos","flutter_secure_storage_web","flutter_secure_storage_windows"]},{"name":"flutter_secure_storage_linux","dependencies":[]},{"name":"flutter_secure_storage_macos","dependencies":[]},{"name":"flutter_secure_storage_web","dependencies":[]},{"name":"flutter_secure_storage_windows","dependencies":[]}],"date_created":"2025-08-20 22:39:45.766368","version":"3.35.1","swift_package_manager_enabled":{"ios":false,"macos":false}}

39
.gitignore vendored
View File

@@ -1,39 +0,0 @@
# 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
app-example

View File

@@ -1,7 +0,0 @@
{
"editor.codeActionsOnSave": {
"source.fixAll": "explicit",
"source.organizeImports": "explicit",
"source.sortMembers": "explicit"
}
}

View File

@@ -1,50 +0,0 @@
# Welcome to your Expo app 👋
This is an [Expo](https://expo.dev) project created with [`create-expo-app`](https://www.npmjs.com/package/create-expo-app).
## Get started
1. Install dependencies
```bash
npm install
```
2. Start the app
```bash
npx expo start
```
In the output, you'll find options to open the app in a
- [development build](https://docs.expo.dev/develop/development-builds/introduction/)
- [Android emulator](https://docs.expo.dev/workflow/android-studio-emulator/)
- [iOS simulator](https://docs.expo.dev/workflow/ios-simulator/)
- [Expo Go](https://expo.dev/go), a limited sandbox for trying out app development with Expo
You can start developing by editing the files inside the **app** directory. This project uses [file-based routing](https://docs.expo.dev/router/introduction).
## Get a fresh project
When you're ready, run:
```bash
npm run reset-project
```
This command will move the starter code to the **app-example** directory and create a blank **app** directory where you can start developing.
## Learn more
To learn more about developing your project with Expo, look at the following resources:
- [Expo documentation](https://docs.expo.dev/): Learn fundamentals, or go into advanced topics with our [guides](https://docs.expo.dev/guides).
- [Learn Expo tutorial](https://docs.expo.dev/tutorial/introduction/): Follow a step-by-step tutorial where you'll create a project that runs on Android, iOS, and the web.
## Join the community
Join our community of developers creating universal apps.
- [Expo on GitHub](https://github.com/expo/expo): View our open source platform and contribute.
- [Discord community](https://chat.expo.dev): Chat with Expo users and ask questions.

View File

@@ -1,51 +0,0 @@
{
"expo": {
"name": "mcbeno",
"slug": "mcbeno",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/images/icon.png",
"scheme": "isotestapp",
"userInterfaceStyle": "automatic",
"newArchEnabled": true,
"ios": {
"supportsTablet": true,
"bundleIdentifier": "com.devbeni.mcbeno"
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/images/icon.png",
"backgroundColor": "#0c0a0a"
},
"edgeToEdgeEnabled": true,
"package": "com.devbeni.mcbeno"
},
"web": {
"bundler": "metro",
"output": "static",
"favicon": "./assets/images/icon.png"
},
"plugins": [
"expo-router",
[
"expo-splash-screen",
{
"image": "./assets/images/icon.png",
"imageWidth": 200,
"resizeMode": "contain",
"backgroundColor": "#0c0a0a"
}
]
],
"experiments": {
"typedRoutes": true
},
"extra": {
"router": {},
"eas": {
"projectId": "972fe547-cd46-4ed0-b9e1-9f13b035e4b7"
}
},
"owner": "devbeni"
}
}

View File

@@ -1,39 +0,0 @@
import { Link, Stack } from 'expo-router';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default function NotFoundScreen() {
return (
<>
<Stack.Screen options={{ title: 'Oops!' }} />
<View style={styles.container}>
<Text style={styles.title}>This screen does not exist.</Text>
<Link href="/" style={styles.link}>
<Text style={styles.linkText}>Go to home screen!</Text>
</Link>
</View>
</>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
padding: 20,
},
title: {
fontSize: 20,
fontWeight: 'bold',
marginBottom: 10,
},
link: {
marginTop: 15,
paddingVertical: 15,
},
linkText: {
color: '#007AFF',
textDecorationLine: 'underline',
},
});

View File

@@ -1,6 +0,0 @@
import { Stack } from "expo-router";
import React from "react";
export default function RootLayout() {
return <Stack screenOptions={{ headerShown: false }} />;
}

View File

@@ -1,228 +0,0 @@
import { MaterialIcons } from '@expo/vector-icons';
import { useRouter } from 'expo-router';
import * as SecureStore from 'expo-secure-store';
import { StatusBar } from 'expo-status-bar';
import React, { useEffect, useState } from "react";
import { ActivityIndicator, Alert, Platform, StyleSheet, Text, TextInput, ToastAndroid, TouchableOpacity, View } from "react-native";
const PRIMARY = '#A24BFA';
const BG = '#0c0a0a';
export default function Index() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [loading, setLoading] = useState(false);
const [autoLogin, setAutoLogin] = useState(false);
const router = useRouter();
useEffect(() => {
(async () => {
const savedEmail = await SecureStore.getItemAsync('email');
const savedPassword = await SecureStore.getItemAsync('password');
if (savedEmail && savedPassword) {
setUsername(savedEmail);
setPassword(savedPassword);
setAutoLogin(true);
setTimeout(() => {
handleLogin(savedEmail, savedPassword, true);
}, 1000);
}
})();
}, []);
async function handleLogin(emailOverride?: string, passwordOverride?: string, isAuto?: boolean) {
setLoading(true);
const user = emailOverride ?? username;
const pass = passwordOverride ?? password;
try {
const response = await fetch('https://menuapi.devbeni.lol/api/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify({ username: user, password: pass })
});
const loginData = await response.json();
if (!loginData || !loginData.token) {
throw new Error('Hibás bejelentkezés vagy hiányzó token!');
}
await SecureStore.setItemAsync('token', loginData.token);
await SecureStore.setItemAsync('email', user);
await SecureStore.setItemAsync('password', pass);
const meResponse = await fetch('https://menuapi.devbeni.lol/api/@me', {
method: 'GET',
headers: {
'Authorization': `Bearer ${loginData.token}`,
'Accept': 'application/json',
},
});
const meData = await meResponse.json();
if (meData && meData.data) {
await SecureStore.setItemAsync('fullName', meData.data.fullName || '');
await SecureStore.setItemAsync('userId', String(meData.data.userId || ''));
}
if (isAuto) {
if (Platform.OS === 'android') {
ToastAndroid.show('Sikeres automatikus bejelentkezés', ToastAndroid.SHORT);
}
}
router.replace('/profile');
} catch (e) {
Alert.alert('Hiba', 'Hibás felhasználónév vagy jelszó, vagy hálózati hiba.');
} finally {
setLoading(false);
setAutoLogin(false);
}
}
return (
<View style={styles.container}>
<StatusBar style="light" backgroundColor={BG} />
<View style={styles.card}>
<Text style={styles.title}>Üdv újra</Text>
<Text style={styles.subtitle}>Jelentkezz be a mymenu fiókodba</Text>
<View style={{ height: 24 }} />
<Text style={styles.label}>Felhasználónév</Text>
<View style={styles.inputRow}>
<MaterialIcons name="email" size={22} color="#bdbdbd" style={{ marginRight: 8 }} />
<TextInput
style={styles.input}
placeholder="valaki@gmail.com"
placeholderTextColor="#aaa"
value={username}
onChangeText={setUsername}
autoCapitalize="none"
/>
</View>
<View style={{ height: 16 }} />
<Text style={styles.label}>Jelszó</Text>
<View style={styles.inputRow}>
<MaterialIcons name="lock" size={22} color="#bdbdbd" style={{ marginRight: 8 }} />
<TextInput
style={styles.input}
placeholder="••••••••"
placeholderTextColor="#aaa"
value={password}
onChangeText={setPassword}
secureTextEntry
/>
</View>
<View style={{ height: 24 }} />
<TouchableOpacity style={styles.button} onPress={() => handleLogin()} disabled={loading}>
{loading ? (
<ActivityIndicator color="#fff" />
) : (
<Text style={styles.buttonText}>Bejelentkezés</Text>
)}
</TouchableOpacity>
</View>
{(loading || autoLogin) && (
<View style={styles.loadingOverlay}>
<ActivityIndicator size="large" color={PRIMARY} />
<Text style={styles.loadingText}>{autoLogin ? 'Bejelentkezés...' : 'Betöltés...'}</Text>
</View>
)}
</View>
);
}
export const options = {
headerShown: false,
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: BG,
justifyContent: 'center',
alignItems: 'center',
},
card: {
width: '90%',
maxWidth: 400,
backgroundColor: 'rgba(24, 20, 28, 0.95)',
borderRadius: 24,
padding: 32,
shadowColor: '#000',
shadowOpacity: 0.3,
shadowRadius: 24,
shadowOffset: { width: 0, height: 8 },
elevation: 8,
},
title: {
color: '#fff',
fontWeight: 'bold',
fontSize: 28,
textAlign: 'center',
marginBottom: 4,
},
subtitle: {
color: '#bdbdbd',
fontSize: 16,
textAlign: 'center',
marginBottom: 24,
},
label: {
color: '#bdbdbd',
fontSize: 14,
marginBottom: 8,
},
inputRow: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: 'rgba(20,18,24,1)',
borderColor: PRIMARY,
borderWidth: 1,
borderRadius: 12,
marginBottom: 16,
paddingHorizontal: 8,
},
input: {
flex: 1,
backgroundColor: 'transparent',
color: '#fff',
paddingHorizontal: 8,
paddingVertical: 12,
fontSize: 16,
borderWidth: 0,
},
button: {
backgroundColor: PRIMARY,
borderRadius: 12,
paddingVertical: 14,
alignItems: 'center',
marginTop: 8,
shadowColor: PRIMARY,
shadowOpacity: 0.3,
shadowRadius: 8,
shadowOffset: { width: 0, height: 2 },
elevation: 2,
},
buttonText: {
color: '#fff',
fontWeight: 'bold',
fontSize: 18,
},
loadingOverlay: {
position: 'absolute',
left: 0,
top: 0,
right: 0,
bottom: 0,
backgroundColor: 'rgba(12,10,10,0.85)',
justifyContent: 'center',
alignItems: 'center',
zIndex: 10,
},
loadingText: {
color: PRIMARY,
fontSize: 18,
marginTop: 16,
fontWeight: 'bold',
},
});

View File

@@ -1,181 +0,0 @@
import { Ionicons, MaterialCommunityIcons, MaterialIcons } from '@expo/vector-icons';
import { useRouter } from 'expo-router';
import * as SecureStore from 'expo-secure-store';
import React, { useEffect, useState } from "react";
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
const PRIMARY = '#A24BFA';
const BG = '#0c0a0a';
export default function Profile() {
const [user, setUser] = useState<any>(null);
const [loading, setLoading] = useState(false);
const router = useRouter();
useEffect(() => {
fetchUser();
}, []);
async function fetchUser() {
setLoading(true);
try {
const token = await SecureStore.getItemAsync('token');
if (!token) {
throw new Error('Nincs elmentett token, kérlek jelentkezz be újra!');
}
const response = await fetch('https://menuapi.devbeni.lol/api/@me', {
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`,
'Accept': 'application/json',
},
});
const data = await response.json();
if (!data || !data.data || !data.data.Data) {
setUser(null);
return;
}
setUser(data.data.Data);
} catch (e) {
setUser(null);
} finally {
setLoading(false);
}
}
async function handleLogout() {
await SecureStore.deleteItemAsync('token');
await SecureStore.deleteItemAsync('email');
await SecureStore.deleteItemAsync('password');
await SecureStore.deleteItemAsync('fullName');
await SecureStore.deleteItemAsync('userId');
router.replace('/');
}
return (
<View style={styles.container}>
<Text style={styles.title}>Profil</Text>
<View style={styles.card}>
<Text style={styles.label}>Név:</Text>
<Text style={styles.value}>{user?.FullName || '-'}</Text>
<Text style={styles.label}>UserID:</Text>
<Text style={styles.value}>{user?.UserID || '-'}</Text>
<Text style={styles.label}>Szerepkör:</Text>
<Text style={styles.value}>{user?.RoleCode || '-'}</Text>
<Text style={styles.label}>Étterem:</Text>
<Text style={styles.value}>{user?.RestaurantName || '-'}</Text>
<TouchableOpacity style={styles.logoutButton} onPress={handleLogout}>
<Text style={styles.logoutText}>Kijelentkezés</Text>
</TouchableOpacity>
</View>
<View style={styles.navBar}>
<NavBar activeTab="profile" />
</View>
</View>
);
}
function NavBar({ activeTab }: { activeTab: string }) {
const router = useRouter();
return (
<View style={styles.navBar}>
<TouchableOpacity style={styles.navItem} onPress={() => router.push('/profile')}>
<MaterialIcons name="person" size={28} color={activeTab === 'profile' ? PRIMARY : '#bdbdbd'} />
<Text style={[styles.navLabel, { color: activeTab === 'profile' ? PRIMARY : '#bdbdbd' }]}>Profilom</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.navItem} onPress={() => router.push('/schedule')}>
<MaterialCommunityIcons name="calendar-month" size={28} color={activeTab === 'schedule' ? PRIMARY : '#bdbdbd'} />
<Text style={[styles.navLabel, { color: activeTab === 'schedule' ? PRIMARY : '#bdbdbd' }]}>Beosztás</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.navItem} onPress={() => router.push('/requests')}>
<Ionicons name="mail" size={28} color={activeTab === 'requests' ? PRIMARY : '#bdbdbd'} />
<Text style={[styles.navLabel, { color: activeTab === 'requests' ? PRIMARY : '#bdbdbd' }]}>Kérelmek</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: BG,
justifyContent: 'center',
alignItems: 'center',
paddingBottom: 64,
},
title: {
color: '#fff',
fontWeight: 'bold',
fontSize: 28,
textAlign: 'center',
marginBottom: 24,
marginTop: 32,
},
card: {
backgroundColor: 'rgba(24, 20, 28, 0.95)',
borderRadius: 24,
padding: 32,
width: '90%',
maxWidth: 400,
shadowColor: '#000',
shadowOpacity: 0.3,
shadowRadius: 24,
shadowOffset: { width: 0, height: 8 },
elevation: 8,
marginBottom: 32,
},
label: {
color: '#bdbdbd',
fontSize: 16,
marginTop: 12,
fontWeight: 'bold',
},
value: {
color: PRIMARY,
fontSize: 18,
marginBottom: 8,
},
navBar: {
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
backgroundColor: 'rgba(24, 20, 28, 0.98)',
borderTopWidth: 1,
borderTopColor: '#222',
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
height: 64,
paddingHorizontal: 16,
},
navItem: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
navLabel: {
fontSize: 13,
marginTop: 2,
fontWeight: 'bold',
},
logoutButton: {
backgroundColor: PRIMARY,
borderRadius: 12,
paddingVertical: 16,
alignItems: 'center',
marginTop: 32,
shadowColor: PRIMARY,
shadowOpacity: 0.3,
shadowRadius: 8,
shadowOffset: { width: 0, height: 2 },
elevation: 2,
},
logoutText: {
color: '#fff',
fontWeight: 'bold',
fontSize: 18,
letterSpacing: 1,
},
});

View File

@@ -1,98 +0,0 @@
import { Ionicons, MaterialCommunityIcons, MaterialIcons } from '@expo/vector-icons';
import { useRouter } from 'expo-router';
import React, { useEffect } from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
const PRIMARY = '#A24BFA';
const BG = '#0c0a0a';
export default function Requests() {
useEffect(() => {
console.log('Requests oldal betöltve');
}, []);
return (
<View style={styles.container}>
<View style={styles.card}>
<Text style={styles.label}>Kérelmek funkció hamarosan</Text>
</View>
<View style={styles.navBar}>
<NavBar activeTab="requests" />
</View>
</View>
);
}
function NavBar({ activeTab }: { activeTab: string }) {
const router = useRouter();
return (
<View style={styles.navBar}>
<TouchableOpacity style={styles.navItem} onPress={() => router.replace('/profile')}>
<MaterialIcons name="person" size={28} color={activeTab === 'profile' ? PRIMARY : '#bdbdbd'} />
<Text style={[styles.navLabel, { color: activeTab === 'profile' ? PRIMARY : '#bdbdbd' }]}>Profilom</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.navItem} onPress={() => router.replace('/schedule')}>
<MaterialCommunityIcons name="calendar-month" size={28} color={activeTab === 'schedule' ? PRIMARY : '#bdbdbd'} />
<Text style={[styles.navLabel, { color: activeTab === 'schedule' ? PRIMARY : '#bdbdbd' }]}>Beosztás</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.navItem} onPress={() => router.replace('/requests')}>
<Ionicons name="mail" size={28} color={activeTab === 'requests' ? PRIMARY : '#bdbdbd'} />
<Text style={[styles.navLabel, { color: activeTab === 'requests' ? PRIMARY : '#bdbdbd' }]}>Kérelmek</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: BG,
justifyContent: 'center',
alignItems: 'center',
paddingBottom: 64,
},
card: {
backgroundColor: 'rgba(24, 20, 28, 0.95)',
borderRadius: 24,
padding: 32,
width: '90%',
maxWidth: 400,
shadowColor: '#000',
shadowOpacity: 0.3,
shadowRadius: 24,
shadowOffset: { width: 0, height: 8 },
elevation: 8,
marginBottom: 32,
marginTop: 32,
},
label: {
color: '#bdbdbd',
fontSize: 16,
marginBottom: 16,
fontWeight: 'bold',
textAlign: 'center',
},
navBar: {
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
backgroundColor: 'rgba(24, 20, 28, 0.98)',
borderTopWidth: 1,
borderTopColor: '#222',
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
height: 64,
paddingHorizontal: 16,
},
navItem: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
navLabel: {
fontSize: 13,
marginTop: 2,
fontWeight: 'bold',
},
});

View File

@@ -1,257 +0,0 @@
import { Ionicons, MaterialCommunityIcons, MaterialIcons } from '@expo/vector-icons';
import { addDays, addWeeks, format, getMonth, getYear, isSameDay, startOfWeek, subWeeks } from 'date-fns';
import { useRouter } from 'expo-router';
import * as SecureStore from 'expo-secure-store';
import React, { useEffect, useState } from "react";
import { ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native";
const PRIMARY = '#A24BFA';
const BG = '#0c0a0a';
export default function Schedule() {
const [currentWeek, setCurrentWeek] = useState(new Date());
const [workdays, setWorkdays] = useState<any[]>([]);
const [loading, setLoading] = useState(false);
const router = useRouter();
useEffect(() => {
fetchWorkdays();
}, [currentWeek]);
async function fetchWorkdays() {
setLoading(true);
try {
const token = await SecureStore.getItemAsync('token');
if (!token) {
throw new Error('Nincs elmentett token, kérlek jelentkezz be újra!');
}
// Az aktuális hét első és utolsó napja
const weekStart = startOfWeek(currentWeek, { weekStartsOn: 1 });
const weekEnd = addDays(weekStart, 6);
const months = new Set([
getMonth(weekStart) + 1,
getMonth(weekEnd) + 1
]);
const years = new Set([
getYear(weekStart),
getYear(weekEnd)
]);
let allWorkdays: any[] = [];
for (const year of years) {
for (const month of months) {
const response = await fetch(`https://menuapi.devbeni.lol/api/@me/schedule?year=${year}&month=${month}`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`,
'Accept': 'application/json',
},
});
const data = await response.json();
if (data && data.data && Array.isArray(data.data.Data)) {
allWorkdays = allWorkdays.concat(data.data.Data);
}
}
}
setWorkdays(allWorkdays);
} catch (e) {
const err = e as any;
if (err.response) {
console.log('API error response:', {
data: err.response.data,
});
} else {
console.log('Network error:', e);
}
setWorkdays([]);
} finally {
setLoading(false);
}
}
function renderCalendar() {
const weekStart = startOfWeek(currentWeek, { weekStartsOn: 1 });
const today = new Date();
// 2 soros grid: első sor 4 nap, második sor 3 nap
const weekDays = Array.from({ length: 7 }, (_, i) => addDays(weekStart, i));
const firstRow = weekDays.slice(0, 4);
const secondRow = weekDays.slice(4);
function renderDayBox(day: string | number | Date) {
const formattedDate = format(day, 'yyyy-MM-dd');
const wd = workdays.find(w => w.WorkDay?.slice(0, 10) === formattedDate);
let bg = '#ede7f6';
let color = '#6a1b9a';
let borderWidth = 0;
if (isSameDay(day, today)) {
borderWidth = 2;
color = PRIMARY;
}
if (wd) {
if (wd.Type === 1) {
bg = '#B388FF';
color = '#311b92';
} else if (wd.Type === 10) {
bg = '#A24BFA';
color = '#fff';
}
}
return (
<View
key={day.toString()}
style={{
flex: 1,
margin: 6,
minWidth: 60,
minHeight: 70,
maxWidth: 120,
maxHeight: 120,
justifyContent: 'center',
alignItems: 'center',
}}
>
<View style={{
backgroundColor: bg,
borderRadius: 18,
borderWidth,
borderColor: PRIMARY,
justifyContent: 'center',
alignItems: 'center',
width: '100%',
minHeight: 60,
paddingVertical: 10,
paddingHorizontal: 4,
shadowColor: '#a24bfa',
shadowOpacity: 0.10,
shadowRadius: 8,
shadowOffset: { width: 0, height: 2 },
overflow: 'hidden',
}}>
<Text style={{ color, fontWeight: 'bold', fontSize: 22, textAlign: 'center', width: '100%' }}>{format(day, 'd')}</Text>
{wd && wd.Type === 1 && (
<Text style={{ color, fontSize: 15, fontWeight: 'bold', marginTop: 4, textAlign: 'center', width: '100%' }} numberOfLines={2} ellipsizeMode="tail">PN</Text>
)}
{wd && wd.Type === 10 && wd.text && (
<Text style={{ color, fontSize: 15, fontWeight: 'bold', marginTop: 4, textAlign: 'center', width: '100%' }} numberOfLines={2} ellipsizeMode="tail">{wd.text}</Text>
)}
</View>
</View>
);
}
return (
<View>
<View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
<TouchableOpacity onPress={() => setCurrentWeek(subWeeks(currentWeek, 1))}><Ionicons name="chevron-back" size={28} color="#fff" /></TouchableOpacity>
<Text style={{ color: '#fff', fontSize: 18, fontWeight: 'bold' }}>{format(weekStart, 'yyyy. MMMM d.') + ' - ' + format(addDays(weekStart, 6), 'MMMM d.')}</Text>
<TouchableOpacity onPress={() => setCurrentWeek(addWeeks(currentWeek, 1))}><Ionicons name="chevron-forward" size={28} color="#fff" /></TouchableOpacity>
</View>
<View style={{ flexDirection: 'row', marginBottom: 4, width: '100%' }}>
{["H", "K", "Sz", "Cs", "P", "Szo", "V"].map(d => (
<Text key={d} style={{ flex: 1, color: '#bdbdbd', textAlign: 'center', fontWeight: 'bold' }}>{d}</Text>
))}
</View>
{loading ? (
<Text style={{ color: '#fff', textAlign: 'center', marginTop: 24 }}>Betöltés</Text>
) : (
<View style={{ width: '100%', alignItems: 'center', justifyContent: 'center' }}>
<View style={{ flexDirection: 'row', width: '100%', justifyContent: 'center' }}>
{firstRow.map(renderDayBox)}
</View>
<View style={{ flexDirection: 'row', width: '75%', justifyContent: 'center' }}>
{secondRow.map(renderDayBox)}
</View>
</View>
)}
</View>
);
}
return (
<ScrollView style={{ flex: 1, backgroundColor: BG }} contentContainerStyle={{ flexGrow: 1, justifyContent: 'center', alignItems: 'center', minHeight: '100%', paddingBottom: 80, width: '100%' }}>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', width: '100%' }}>
<View style={[styles.card, { alignSelf: 'center', marginTop: 48, marginBottom: 48, width: '100%' }]}>
<Text style={styles.label}>Beosztás naptár</Text>
{(!loading && workdays.length === 0) && (
<Text style={{ color: '#ff5252', textAlign: 'center', marginBottom: 12, fontWeight: 'bold' }}>
Nincs beosztás vagy nem vagy bejelentkezve!
</Text>
)}
{renderCalendar()}
</View>
</View>
<View style={styles.navBar}>
<NavBar activeTab="schedule" />
</View>
</ScrollView>
);
}
function NavBar({ activeTab }: { activeTab: string }) {
const router = useRouter();
return (
<View style={styles.navBar}>
<TouchableOpacity style={styles.navItem} onPress={() => router.push('/profile')}>
<MaterialIcons name="person" size={28} color={activeTab === 'profile' ? PRIMARY : '#bdbdbd'} />
<Text style={[styles.navLabel, { color: activeTab === 'profile' ? PRIMARY : '#bdbdbd' }]}>Profilom</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.navItem} onPress={() => router.push('/schedule')}>
<MaterialCommunityIcons name="calendar-month" size={28} color={activeTab === 'schedule' ? PRIMARY : '#bdbdbd'} />
<Text style={[styles.navLabel, { color: activeTab === 'schedule' ? PRIMARY : '#bdbdbd' }]}>Beosztás</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.navItem} onPress={() => router.push('/requests')}>
<Ionicons name="mail" size={28} color={activeTab === 'requests' ? PRIMARY : '#bdbdbd'} />
<Text style={[styles.navLabel, { color: activeTab === 'requests' ? PRIMARY : '#bdbdbd' }]}>Kérelmek</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
card: {
backgroundColor: 'rgba(24, 20, 28, 0.95)',
borderRadius: 24,
padding: 32,
width: '90%',
maxWidth: 400,
shadowColor: '#000',
shadowOpacity: 0.3,
shadowRadius: 24,
shadowOffset: { width: 0, height: 8 },
elevation: 8,
marginBottom: 32,
marginTop: 32,
},
label: {
color: '#bdbdbd',
fontSize: 16,
marginBottom: 16,
fontWeight: 'bold',
textAlign: 'center',
},
navBar: {
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
backgroundColor: 'rgba(24, 20, 28, 0.98)',
borderTopWidth: 1,
borderTopColor: '#222',
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
height: 64,
paddingHorizontal: 16,
},
navItem: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
navLabel: {
fontSize: 13,
marginTop: 2,
fontWeight: 'bold',
},
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 301 KiB

View File

@@ -1,24 +0,0 @@
{
"cli": {
"version": ">= 16.17.3",
"appVersionSource": "remote"
},
"build": {
"development": {
"developmentClient": true,
"distribution": "internal",
"ios": {
"simulator": true
}
},
"preview": {
"distribution": "internal"
},
"production": {
"autoIncrement": true
}
},
"submit": {
"production": {}
}
}

View File

@@ -1,10 +0,0 @@
// https://docs.expo.dev/guides/using-eslint/
const { defineConfig } = require('eslint/config');
const expoConfig = require('eslint-config-expo/flat');
module.exports = defineConfig([
expoConfig,
{
ignores: ['dist/*'],
},
]);

32
ios/.gitignore vendored
View File

@@ -1,32 +0,0 @@
# OSX
#
.DS_Store
# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
project.xcworkspace
.xcode.env.local
# Bundle artifacts
*.jsbundle
# CocoaPods
/Pods/
/.DerivedData

View File

@@ -1,11 +0,0 @@
# This `.xcode.env` file is versioned and is used to source the environment
# used when running script phases inside Xcode.
# To customize your local environment, you can create an `.xcode.env.local`
# file that is not versioned.
# NODE_BINARY variable contains the PATH to the node executable.
#
# Customize the NODE_BINARY variable here.
# For example, to use nvm with brew, add the following line
# . "$(brew --prefix nvm)/nvm.sh" --no-use
export NODE_BINARY=$(command -v node)

View File

@@ -1,64 +0,0 @@
require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods")
require 'json'
podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {}
ENV['RCT_NEW_ARCH_ENABLED'] = '0' if podfile_properties['newArchEnabled'] == 'false'
ENV['EX_DEV_CLIENT_NETWORK_INSPECTOR'] = podfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR']
platform :ios, podfile_properties['ios.deploymentTarget'] || '15.1'
install! 'cocoapods',
:deterministic_uuids => false
prepare_react_native_project!
target 'isotestapp' do
use_expo_modules!
if ENV['EXPO_USE_COMMUNITY_AUTOLINKING'] == '1'
config_command = ['node', '-e', "process.argv=['', '', 'config'];require('@react-native-community/cli').run()"];
else
config_command = [
'npx',
'expo-modules-autolinking',
'react-native-config',
'--json',
'--platform',
'ios'
]
end
config = use_native_modules!(config_command)
use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks']
use_frameworks! :linkage => ENV['USE_FRAMEWORKS'].to_sym if ENV['USE_FRAMEWORKS']
use_react_native!(
:path => config[:reactNativePath],
:hermes_enabled => podfile_properties['expo.jsEngine'] == nil || podfile_properties['expo.jsEngine'] == 'hermes',
# An absolute path to your application root.
:app_path => "#{Pod::Config.instance.installation_root}/..",
:privacy_file_aggregation_enabled => podfile_properties['apple.privacyManifestAggregationEnabled'] != 'false',
)
post_install do |installer|
react_native_post_install(
installer,
config[:reactNativePath],
:mac_catalyst_enabled => false,
:ccache_enabled => podfile_properties['apple.ccacheEnabled'] == 'true',
)
# This is necessary for Xcode 14, because it signs resource bundles by default
# when building for devices.
installer.target_installation_results.pod_target_installation_results
.each do |pod_name, target_installation_result|
target_installation_result.resource_bundle_targets.each do |resource_bundle_target|
resource_bundle_target.build_configurations.each do |config|
config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
end
end
end
end
end

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +0,0 @@
{
"expo.jsEngine": "hermes",
"EX_DEV_CLIENT_NETWORK_INSPECTOR": "true",
"newArchEnabled": "true"
}

View File

@@ -1,549 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; };
8F1408209307D6E4C7DAFA8C /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 62E7897A0A46BEBD6E3BE2DD /* PrivacyInfo.xcprivacy */; };
968B1E49021D53E4C6340251 /* libPods-isotestapp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 72BC77FAEBE1CD82A9A40DFA /* libPods-isotestapp.a */; };
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; };
CE2FA99505850B4C98896E60 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19ABB810D140C55E07163F9F /* ExpoModulesProvider.swift */; };
F11748422D0307B40044C1D9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11748412D0307B40044C1D9 /* AppDelegate.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
00768180FA69209EEBD93158 /* Pods-isotestapp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-isotestapp.debug.xcconfig"; path = "Target Support Files/Pods-isotestapp/Pods-isotestapp.debug.xcconfig"; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* isotestapp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = isotestapp.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = isotestapp/Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = isotestapp/Info.plist; sourceTree = "<group>"; };
19ABB810D140C55E07163F9F /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-isotestapp/ExpoModulesProvider.swift"; sourceTree = "<group>"; };
458F41F593E403B1A8626125 /* Pods-isotestapp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-isotestapp.release.xcconfig"; path = "Target Support Files/Pods-isotestapp/Pods-isotestapp.release.xcconfig"; sourceTree = "<group>"; };
62E7897A0A46BEBD6E3BE2DD /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = isotestapp/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
72BC77FAEBE1CD82A9A40DFA /* libPods-isotestapp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-isotestapp.a"; sourceTree = BUILT_PRODUCTS_DIR; };
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = isotestapp/SplashScreen.storyboard; sourceTree = "<group>"; };
BB2F792C24A3F905000567C9 /* Expo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Expo.plist; sourceTree = "<group>"; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
F11748412D0307B40044C1D9 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = isotestapp/AppDelegate.swift; sourceTree = "<group>"; };
F11748442D0722820044C1D9 /* isotestapp-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "isotestapp-Bridging-Header.h"; path = "isotestapp/isotestapp-Bridging-Header.h"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
968B1E49021D53E4C6340251 /* libPods-isotestapp.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
11714AEDC0523D1ACD1795A5 /* isotestapp */ = {
isa = PBXGroup;
children = (
19ABB810D140C55E07163F9F /* ExpoModulesProvider.swift */,
);
name = isotestapp;
sourceTree = "<group>";
};
13B07FAE1A68108700A75B9A /* isotestapp */ = {
isa = PBXGroup;
children = (
F11748412D0307B40044C1D9 /* AppDelegate.swift */,
F11748442D0722820044C1D9 /* isotestapp-Bridging-Header.h */,
BB2F792B24A3F905000567C9 /* Supporting */,
13B07FB51A68108700A75B9A /* Images.xcassets */,
13B07FB61A68108700A75B9A /* Info.plist */,
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */,
62E7897A0A46BEBD6E3BE2DD /* PrivacyInfo.xcprivacy */,
);
name = isotestapp;
sourceTree = "<group>";
};
25A01EAB6BB811198435ECFD /* Pods */ = {
isa = PBXGroup;
children = (
00768180FA69209EEBD93158 /* Pods-isotestapp.debug.xcconfig */,
458F41F593E403B1A8626125 /* Pods-isotestapp.release.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
isa = PBXGroup;
children = (
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
72BC77FAEBE1CD82A9A40DFA /* libPods-isotestapp.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
isa = PBXGroup;
children = (
);
name = Libraries;
sourceTree = "<group>";
};
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
13B07FAE1A68108700A75B9A /* isotestapp */,
832341AE1AAA6A7D00B99B32 /* Libraries */,
83CBBA001A601CBA00E9B192 /* Products */,
2D16E6871FA4F8E400B85C8A /* Frameworks */,
25A01EAB6BB811198435ECFD /* Pods */,
E1680B93FDBA9510CA170ED6 /* ExpoModulesProviders */,
);
indentWidth = 2;
sourceTree = "<group>";
tabWidth = 2;
usesTabs = 0;
};
83CBBA001A601CBA00E9B192 /* Products */ = {
isa = PBXGroup;
children = (
13B07F961A680F5B00A75B9A /* isotestapp.app */,
);
name = Products;
sourceTree = "<group>";
};
BB2F792B24A3F905000567C9 /* Supporting */ = {
isa = PBXGroup;
children = (
BB2F792C24A3F905000567C9 /* Expo.plist */,
);
name = Supporting;
path = isotestapp/Supporting;
sourceTree = "<group>";
};
E1680B93FDBA9510CA170ED6 /* ExpoModulesProviders */ = {
isa = PBXGroup;
children = (
11714AEDC0523D1ACD1795A5 /* isotestapp */,
);
name = ExpoModulesProviders;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
13B07F861A680F5B00A75B9A /* isotestapp */ = {
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "isotestapp" */;
buildPhases = (
08A4A3CD28434E44B6B9DE2E /* [CP] Check Pods Manifest.lock */,
D241A0BDABE4CF465A81A48E /* [Expo] Configure project */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */,
92D5307D8A6AEFC8E5E85093 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = isotestapp;
productName = isotestapp;
productReference = 13B07F961A680F5B00A75B9A /* isotestapp.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
83CBB9F71A601CBA00E9B192 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1130;
TargetAttributes = {
13B07F861A680F5B00A75B9A = {
LastSwiftMigration = 1250;
};
};
};
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "isotestapp" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 83CBB9F61A601CBA00E9B192;
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
13B07F861A680F5B00A75B9A /* isotestapp */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
13B07F8E1A680F5B00A75B9A /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */,
8F1408209307D6E4C7DAFA8C /* PrivacyInfo.xcprivacy in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Bundle React Native code and images";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios absolute | tail -n 1)\"\nfi\n\nif [[ -z \"$CLI_PATH\" ]]; then\n # Use Expo CLI\n export CLI_PATH=\"$(\"$NODE_BINARY\" --print \"require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })\")\"\nfi\nif [[ -z \"$BUNDLE_COMMAND\" ]]; then\n # Default Expo CLI command for bundling\n export BUNDLE_COMMAND=\"export:embed\"\nfi\n\n# Source .xcode.env.updates if it exists to allow\n# SKIP_BUNDLING to be unset if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.updates\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.updates\"\nfi\n# Source local changes to allow overrides\n# if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"`\n\n";
};
08A4A3CD28434E44B6B9DE2E /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-isotestapp-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-isotestapp/Pods-isotestapp-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/EXApplication/ExpoApplication_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/ExpoConstants_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/EXNotifications/ExpoNotifications_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoSystemUI/ExpoSystemUI_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly/RCT-Folly_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/React-Core_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact/React-cxxreact_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/boost/boost_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/glog/glog_privacy.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoApplication_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoConstants_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoNotifications_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoSystemUI_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCT-Folly_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-Core_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-cxxreact_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SDWebImage.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/boost_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/glog_privacy.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-isotestapp/Pods-isotestapp-resources.sh\"\n";
showEnvVarsInLog = 0;
};
92D5307D8A6AEFC8E5E85093 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-isotestapp/Pods-isotestapp-frameworks.sh",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-isotestapp/Pods-isotestapp-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
D241A0BDABE4CF465A81A48E /* [Expo] Configure project */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "[Expo] Configure project";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-isotestapp/expo-configure-project.sh\"\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
13B07F871A680F5B00A75B9A /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F11748422D0307B40044C1D9 /* AppDelegate.swift in Sources */,
CE2FA99505850B4C98896E60 /* ExpoModulesProvider.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 00768180FA69209EEBD93158 /* Pods-isotestapp.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = isotestapp/isotestapp.entitlements;
CURRENT_PROJECT_VERSION = 1;
ENABLE_BITCODE = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
"FB_SONARKIT_ENABLED=1",
);
INFOPLIST_FILE = isotestapp/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
"-lc++",
);
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.iso-test-app";
PRODUCT_NAME = isotestapp;
SWIFT_OBJC_BRIDGING_HEADER = "isotestapp/isotestapp-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 458F41F593E403B1A8626125 /* Pods-isotestapp.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = isotestapp/isotestapp.entitlements;
CURRENT_PROJECT_VERSION = 1;
INFOPLIST_FILE = isotestapp/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
"-lc++",
);
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.iso-test-app";
PRODUCT_NAME = isotestapp;
SWIFT_OBJC_BRIDGING_HEADER = "isotestapp/isotestapp-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
83CBBA201A601CBA00E9B192 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++20";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
LD_RUNPATH_SEARCH_PATHS = (
/usr/lib/swift,
"$(inherited)",
);
LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift\"$(inherited)\"";
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/.pnpm/react-native@0.79.5_@babel+core@7.28.0_@types+react@19.0.14_react@19.0.0/node_modules/react-native";
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
USE_HERMES = true;
};
name = Debug;
};
83CBBA211A601CBA00E9B192 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++20";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
LD_RUNPATH_SEARCH_PATHS = (
/usr/lib/swift,
"$(inherited)",
);
LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift\"$(inherited)\"";
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/.pnpm/react-native@0.79.5_@babel+core@7.28.0_@types+react@19.0.14_react@19.0.0/node_modules/react-native";
SDKROOT = iphoneos;
USE_HERMES = true;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "isotestapp" */ = {
isa = XCConfigurationList;
buildConfigurations = (
13B07F941A680F5B00A75B9A /* Debug */,
13B07F951A680F5B00A75B9A /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "isotestapp" */ = {
isa = XCConfigurationList;
buildConfigurations = (
83CBBA201A601CBA00E9B192 /* Debug */,
83CBBA211A601CBA00E9B192 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
}

View File

@@ -1,88 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1130"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "isotestapp.app"
BlueprintName = "isotestapp"
ReferencedContainer = "container:isotestapp.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
BuildableName = "isotestappTests.xctest"
BlueprintName = "isotestappTests"
ReferencedContainer = "container:isotestapp.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "isotestapp.app"
BlueprintName = "isotestapp"
ReferencedContainer = "container:isotestapp.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "isotestapp.app"
BlueprintName = "isotestapp"
ReferencedContainer = "container:isotestapp.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:isotestapp.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -1,70 +0,0 @@
import Expo
import React
import ReactAppDependencyProvider
@UIApplicationMain
public class AppDelegate: ExpoAppDelegate {
var window: UIWindow?
var reactNativeDelegate: ExpoReactNativeFactoryDelegate?
var reactNativeFactory: RCTReactNativeFactory?
public override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
let delegate = ReactNativeDelegate()
let factory = ExpoReactNativeFactory(delegate: delegate)
delegate.dependencyProvider = RCTAppDependencyProvider()
reactNativeDelegate = delegate
reactNativeFactory = factory
bindReactNativeFactory(factory)
#if os(iOS) || os(tvOS)
window = UIWindow(frame: UIScreen.main.bounds)
factory.startReactNative(
withModuleName: "main",
in: window,
launchOptions: launchOptions)
#endif
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
// Linking API
public override func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
return super.application(app, open: url, options: options) || RCTLinkingManager.application(app, open: url, options: options)
}
// Universal Links
public override func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
let result = RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
return super.application(application, continue: userActivity, restorationHandler: restorationHandler) || result
}
}
class ReactNativeDelegate: ExpoReactNativeFactoryDelegate {
// Extension point for config-plugins
override func sourceURL(for bridge: RCTBridge) -> URL? {
// needed to return the correct URL for expo-dev-client.
bridge.bundleURL ?? bundleURL()
}
override func bundleURL() -> URL? {
#if DEBUG
return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: ".expo/.virtual-metro-entry")
#else
return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
#endif
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -1,14 +0,0 @@
{
"images": [
{
"filename": "App-Icon-1024x1024@1x.png",
"idiom": "universal",
"platform": "ios",
"size": "1024x1024"
}
],
"info": {
"version": 1,
"author": "expo"
}
}

View File

@@ -1,6 +0,0 @@
{
"info" : {
"version" : 1,
"author" : "expo"
}
}

View File

@@ -1,20 +0,0 @@
{
"colors": [
{
"color": {
"components": {
"alpha": "1.000",
"blue": "1.00000000000000",
"green": "1.00000000000000",
"red": "1.00000000000000"
},
"color-space": "srgb"
},
"idiom": "universal"
}
],
"info": {
"version": 1,
"author": "expo"
}
}

View File

@@ -1,23 +0,0 @@
{
"images": [
{
"idiom": "universal",
"filename": "image.png",
"scale": "1x"
},
{
"idiom": "universal",
"filename": "image@2x.png",
"scale": "2x"
},
{
"idiom": "universal",
"filename": "image@3x.png",
"scale": "3x"
}
],
"info": {
"version": 1,
"author": "expo"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

View File

@@ -1,79 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>iso-test-app</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>isotestapp</string>
<string>com.anonymous.iso-test-app</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>12.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
<key>NSUserActivityTypes</key>
<array>
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
</array>
<key>UILaunchStoryboardName</key>
<string>SplashScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>UIRequiresFullScreen</key>
<false/>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleDefault</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIUserInterfaceStyle</key>
<string>Automatic</string>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>

View File

@@ -1,48 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
<string>0A2A.1</string>
<string>3B52.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>E174.1</string>
<string>85F4.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
</array>
</dict>
</array>
<key>NSPrivacyCollectedDataTypes</key>
<array/>
<key>NSPrivacyTracking</key>
<false/>
</dict>
</plist>

View File

@@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="EXPO-VIEWCONTROLLER-1">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<scene sceneID="EXPO-SCENE-1">
<objects>
<viewController storyboardIdentifier="SplashScreenViewController" id="EXPO-VIEWCONTROLLER-1" sceneMemberID="viewController">
<view key="view" userInteractionEnabled="NO" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="EXPO-ContainerView" userLabel="ContainerView">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView id="EXPO-SplashScreen" userLabel="SplashScreenLogo" image="SplashScreenLogo" contentMode="scaleAspectFit" clipsSubviews="true" userInteractionEnabled="false" translatesAutoresizingMaskIntoConstraints="false">
<rect key="frame" x="96.5" y="326" width="200" height="200"/>
</imageView>
</subviews>
<viewLayoutGuide key="safeArea" id="Rmq-lb-GrQ"/>
<constraints>
<constraint firstItem="EXPO-SplashScreen" firstAttribute="centerX" secondItem="EXPO-ContainerView" secondAttribute="centerX" id="cad2ab56f97c5429bf29decf850647a4216861d4"/>
<constraint firstItem="EXPO-SplashScreen" firstAttribute="centerY" secondItem="EXPO-ContainerView" secondAttribute="centerY" id="1a145271b085b6ce89b1405a310f5b1bb7656595"/>
</constraints>
<color key="backgroundColor" name="SplashScreenBackground"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="EXPO-PLACEHOLDER-1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="0.0" y="0.0"/>
</scene>
</scenes>
<resources>
<image name="SplashScreenLogo" width="200" height="200"/>
<namedColor name="SplashScreenBackground">
<color alpha="1.000" blue="1.00000000000000" green="1.00000000000000" red="1.00000000000000" customColorSpace="sRGB" colorSpace="custom"/>
</namedColor>
</resources>
</document>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>EXUpdatesCheckOnLaunch</key>
<string>ALWAYS</string>
<key>EXUpdatesEnabled</key>
<false/>
<key>EXUpdatesLaunchWaitMs</key>
<integer>0</integer>
</dict>
</plist>

View File

@@ -1,3 +0,0 @@
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>

33
lib/main.dart Normal file
View File

@@ -0,0 +1,33 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'screens/login_screen.dart';
import 'screens/profile_screen.dart';
import 'screens/schedule_screen.dart';
import 'services/auth_service.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => AuthService(),
child: MaterialApp(
title: 'ISO Flutter',
theme: ThemeData.dark().copyWith(
primaryColor: Color(0xFFA24BFA),
scaffoldBackgroundColor: Color(0xFF0c0a0a),
),
initialRoute: '/',
routes: {
'/': (context) => LoginScreen(),
'/profile': (context) => ProfileScreen(),
'/schedule': (context) => ScheduleScreen(),
},
),
);
}
}

View File

@@ -0,0 +1,58 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../services/auth_service.dart';
class LoginScreen extends StatefulWidget {
@override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final _userCtrl = TextEditingController();
final _pwCtrl = TextEditingController();
bool _loading = false;
@override
Widget build(BuildContext context) {
final auth = Provider.of<AuthService>(context);
// Auto-redirect if already logged in
if (auth.token != null) {
Future.microtask(() => Navigator.pushReplacementNamed(context, '/profile'));
}
return Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Bejelentkezés', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
SizedBox(height: 16),
TextField(controller: _userCtrl, decoration: InputDecoration(labelText: 'Felhasználó')),
SizedBox(height: 8),
TextField(controller: _pwCtrl, decoration: InputDecoration(labelText: 'Jelszó'), obscureText: true),
SizedBox(height: 16),
ElevatedButton(
onPressed: _loading ? null : () async {
final username = _userCtrl.text.trim();
final password = _pwCtrl.text.trim();
if (username.isEmpty || password.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Kérlek add meg a felhasználónevet és jelszót')));
return;
}
setState(() { _loading = true; });
final ok = await auth.login(username, password);
setState(() { _loading = false; });
if (ok) Navigator.pushReplacementNamed(context, '/profile');
else ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Bejelentkezés sikertelen')));
},
child: _loading ? SizedBox(height: 16, width: 16, child: CircularProgressIndicator(strokeWidth: 2)) : Text('Bejelentkezés'),
)
],
),
),
),
);
}
}

View File

@@ -0,0 +1,31 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../services/auth_service.dart';
class ProfileScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final auth = Provider.of<AuthService>(context);
final profile = auth.profile;
return Scaffold(
appBar: AppBar(title: Text('Profil')),
body: Center(
child: profile == null ? Text('Nincs profil') : Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(profile['FullName'] ?? '', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
SizedBox(height: 8),
Text('UserID: ${profile['UserID'] ?? ''}'),
SizedBox(height: 16),
Row(mainAxisSize: MainAxisSize.min, children: [
ElevatedButton(onPressed: () async { await auth.logout(); Navigator.pushReplacementNamed(context, '/'); }, child: Text('Kijelentkezés')),
SizedBox(width: 12),
ElevatedButton(onPressed: () async { await auth.loadProfile(); }, child: Text('Frissít'))
])
],
),
),
);
}
}

View File

@@ -0,0 +1,96 @@
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import '../services/auth_service.dart';
class ScheduleScreen extends StatefulWidget {
@override
_ScheduleScreenState createState() => _ScheduleScreenState();
}
class _ScheduleScreenState extends State<ScheduleScreen> {
DateTime currentWeek = DateTime.now();
bool loading = false;
List<dynamic> workdays = [];
@override
Widget build(BuildContext context) {
final df = DateFormat('yyyy. MMM d.');
final weekStart = currentWeek.subtract(Duration(days: currentWeek.weekday - 1));
final weekDays = List.generate(7, (i) => weekStart.add(Duration(days: i)));
return Scaffold(
appBar: AppBar(title: Text('Beosztás')),
body: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
children: [
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
IconButton(icon: Icon(Icons.chevron_left), onPressed: () { setState(() { currentWeek = currentWeek.subtract(Duration(days: 7)); }); fetchWorkdays(); }),
Text('${df.format(weekStart)} - ${df.format(weekStart.add(Duration(days:6)))}', style: TextStyle(fontWeight: FontWeight.bold)),
IconButton(icon: Icon(Icons.chevron_right), onPressed: () { setState(() { currentWeek = currentWeek.add(Duration(days: 7)); }); fetchWorkdays(); }),
]),
SizedBox(height: 8),
loading ? CircularProgressIndicator() : Expanded(
child: LayoutBuilder(builder: (ctx, cons) {
final cross = cons.maxWidth > 480 ? 4 : 2;
return GridView.count(
crossAxisCount: cross,
childAspectRatio: 0.9,
children: weekDays.map((day) {
final formatted = DateFormat('yyyy-MM-dd').format(day);
final wd = workdays.firstWhere((w) => (w['WorkDay'] ?? '').toString().substring(0,10) == formatted, orElse: () => null);
String title = '';
if (wd != null) {
if (wd['Type'] == 1) title = 'PN';
else if (wd['Type'] == 10) title = wd['text'] ?? '';
}
return Card(
color: wd != null && wd['Type'] == 10 ? Color(0xFFA24BFA) : (wd != null && wd['Type'] == 1 ? Color(0xFFB388FF) : Color(0xFFede7f6)),
child: Center(
child: Column(mainAxisSize: MainAxisSize.min, children: [
Text('${day.day}', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
SizedBox(height: 6),
Text(title, style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold)),
]),
),
);
}).toList(),
);
})
)
],
),
),
);
}
Future<void> fetchWorkdays() async {
setState(() { loading = true; });
final auth = Provider.of<AuthService>(context, listen: false);
final token = auth.token;
if (token == null) { setState(() { workdays = []; loading = false; }); return; }
final weekStart = currentWeek.subtract(Duration(days: currentWeek.weekday - 1));
final weekEnd = weekStart.add(Duration(days: 6));
final months = {weekStart.month, weekEnd.month};
final years = {weekStart.year, weekEnd.year};
List all = [];
for (final y in years) {
for (final m in months) {
try {
final resList = await auth.fetchSchedule(y, m);
if (resList.isNotEmpty) all.addAll(resList);
} catch (e) {
// ignore per-month errors
}
}
}
setState(() { workdays = all; loading = false; });
}
@override
void initState() {
super.initState();
fetchWorkdays();
}
}

View File

@@ -0,0 +1,83 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:http/http.dart' as http;
class AuthService extends ChangeNotifier {
final _storage = const FlutterSecureStorage();
String? token;
Map<String, dynamic>? profile;
final _base = 'https://menuapi.devbeni.lol/api';
AuthService() {
_loadToken();
}
/// Convenience wrapper that returns the Data array for schedule or empty list
Future<List<dynamic>> fetchSchedule(int year, int month) async {
final resp = await _httpGet('/@me/schedule?year=$year&month=$month');
if (resp == null) return [];
try {
if (resp['data'] != null && resp['data']['Data'] is List) {
return List<dynamic>.from(resp['data']['Data']);
}
} catch (e) {
return [];
}
return [];
}
Future<void> loadProfile() async {
if (token == null) return;
final res = await http.get(
Uri.parse('https://menuapi.devbeni.lol/api/me'),
headers: {'Authorization': 'Bearer $token'},
);
if (res.statusCode == 200) {
profile = jsonDecode(res.body)['data'];
notifyListeners();
}
}
Future<bool> login(String username, String password) async {
try {
final res = await http.post(
Uri.parse('$_base/login'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'username': username, 'password': password}),
);
if (res.statusCode != 200) return false;
final data = jsonDecode(res.body);
// token might be in different places; try common keys
token = data['token'] ?? data['access_token'] ?? (data['data'] != null ? data['data']['token'] : null);
if (token == null) return false;
await _storage.write(key: 'token', value: token);
await loadProfile();
notifyListeners();
return true;
} catch (e) {
return false;
}
}
Future<void> logout() async {
token = null;
profile = null;
await _storage.delete(key: 'token');
notifyListeners();
}
Future<dynamic> _httpGet(String path) async {
if (token == null) return null;
final res = await http.get(Uri.parse('$_base$path'), headers: {'Authorization': 'Bearer $token'});
if (res.statusCode == 200) return jsonDecode(res.body);
return null;
}
Future<void> _loadToken() async {
token = await _storage.read(key: 'token');
if (token != null) await loadProfile();
notifyListeners();
}
}

View File

@@ -1,59 +0,0 @@
{
"name": "mcbeno",
"main": "expo-router/entry",
"version": "1.0.0",
"scripts": {
"start": "expo start",
"android": "expo run:android",
"ios": "expo run:ios",
"web": "expo start --web",
"lint": "expo lint",
"build": "expo build:ios && expo build:android"
},
"dependencies": {
"@expo/vector-icons": "^14.1.0",
"@react-navigation/bottom-tabs": "^7.3.10",
"@react-navigation/elements": "^2.3.8",
"@react-navigation/native": "^7.1.6",
"axios": "^1.11.0",
"date-fns": "^4.1.0",
"expo": "~53.0.20",
"expo-blur": "~14.1.5",
"expo-constants": "~17.1.7",
"expo-font": "~13.3.2",
"expo-haptics": "~14.1.4",
"expo-image": "~2.4.0",
"expo-linking": "~7.1.7",
"expo-notifications": "~0.31.4",
"expo-router": "~5.1.4",
"expo-secure-store": "^14.2.3",
"expo-splash-screen": "~0.30.10",
"expo-status-bar": "~2.2.3",
"expo-symbols": "~0.4.5",
"expo-system-ui": "~5.0.10",
"expo-web-browser": "~14.2.0",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-native": "0.79.5",
"react-native-gesture-handler": "~2.24.0",
"react-native-reanimated": "~3.17.4",
"react-native-safe-area-context": "5.4.0",
"react-native-screens": "~4.11.1",
"react-native-web": "~0.20.0",
"react-native-webview": "13.13.5"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@types/date-fns": "^2.6.3",
"@types/react": "~19.0.10",
"eslint": "^9.25.0",
"eslint-config-expo": "~9.2.0",
"typescript": "~5.8.3"
},
"private": true,
"pnpm": {
"onlyBuiltDependencies": [
"unrs-resolver"
]
}
}

8778
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

306
pubspec.lock Normal file
View File

@@ -0,0 +1,306 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: transitive
description:
name: async
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
url: "https://pub.dev"
source: hosted
version: "2.13.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
characters:
dependency: transitive
description:
name: characters
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
url: "https://pub.dev"
source: hosted
version: "1.4.0"
clock:
dependency: transitive
description:
name: clock
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
url: "https://pub.dev"
source: hosted
version: "1.1.2"
collection:
dependency: transitive
description:
name: collection
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
url: "https://pub.dev"
source: hosted
version: "1.19.1"
fake_async:
dependency: transitive
description:
name: fake_async
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
url: "https://pub.dev"
source: hosted
version: "1.3.3"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_secure_storage:
dependency: "direct main"
description:
name: flutter_secure_storage
sha256: "22dbf16f23a4bcf9d35e51be1c84ad5bb6f627750565edd70dab70f3ff5fff8f"
url: "https://pub.dev"
source: hosted
version: "8.1.0"
flutter_secure_storage_linux:
dependency: transitive
description:
name: flutter_secure_storage_linux
sha256: be76c1d24a97d0b98f8b54bce6b481a380a6590df992d0098f868ad54dc8f688
url: "https://pub.dev"
source: hosted
version: "1.2.3"
flutter_secure_storage_macos:
dependency: transitive
description:
name: flutter_secure_storage_macos
sha256: "6c0a2795a2d1de26ae202a0d78527d163f4acbb11cde4c75c670f3a0fc064247"
url: "https://pub.dev"
source: hosted
version: "3.1.3"
flutter_secure_storage_platform_interface:
dependency: transitive
description:
name: flutter_secure_storage_platform_interface
sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8
url: "https://pub.dev"
source: hosted
version: "1.1.2"
flutter_secure_storage_web:
dependency: transitive
description:
name: flutter_secure_storage_web
sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9
url: "https://pub.dev"
source: hosted
version: "1.2.1"
flutter_secure_storage_windows:
dependency: transitive
description:
name: flutter_secure_storage_windows
sha256: "38f9501c7cb6f38961ef0e1eacacee2b2d4715c63cc83fe56449c4d3d0b47255"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
http:
dependency: "direct main"
description:
name: http
sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2"
url: "https://pub.dev"
source: hosted
version: "0.13.6"
http_parser:
dependency: transitive
description:
name: http_parser
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
url: "https://pub.dev"
source: hosted
version: "4.1.2"
intl:
dependency: "direct main"
description:
name: intl
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
url: "https://pub.dev"
source: hosted
version: "0.18.1"
js:
dependency: transitive
description:
name: js
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
url: "https://pub.dev"
source: hosted
version: "0.6.7"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0"
url: "https://pub.dev"
source: hosted
version: "11.0.1"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
url: "https://pub.dev"
source: hosted
version: "3.0.10"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
url: "https://pub.dev"
source: hosted
version: "3.0.2"
matcher:
dependency: transitive
description:
name: matcher
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
url: "https://pub.dev"
source: hosted
version: "0.12.17"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev"
source: hosted
version: "0.11.1"
meta:
dependency: transitive
description:
name: meta
sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
url: "https://pub.dev"
source: hosted
version: "1.16.0"
nested:
dependency: transitive
description:
name: nested
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
path:
dependency: transitive
description:
name: path
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
url: "https://pub.dev"
source: hosted
version: "1.9.1"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://pub.dev"
source: hosted
version: "2.1.8"
provider:
dependency: "direct main"
description:
name: provider
sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272"
url: "https://pub.dev"
source: hosted
version: "6.1.5+1"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
source_span:
dependency: transitive
description:
name: source_span
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
url: "https://pub.dev"
source: hosted
version: "1.10.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
url: "https://pub.dev"
source: hosted
version: "1.12.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
url: "https://pub.dev"
source: hosted
version: "1.4.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
url: "https://pub.dev"
source: hosted
version: "1.2.2"
test_api:
dependency: transitive
description:
name: test_api
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
url: "https://pub.dev"
source: hosted
version: "0.7.6"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
url: "https://pub.dev"
source: hosted
version: "1.4.0"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
url: "https://pub.dev"
source: hosted
version: "2.2.0"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60"
url: "https://pub.dev"
source: hosted
version: "15.0.2"
sdks:
dart: ">=3.8.0-0 <4.0.0"
flutter: ">=3.18.0-18.0.pre.54"

21
pubspec.yaml Normal file
View File

@@ -0,0 +1,21 @@
name: iso_flutter_app
description: Minimal Flutter port of the React Native app (login, profile, weekly schedule)
publish_to: 'none'
version: 0.0.1
environment:
sdk: ">=2.18.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
http: ^0.13.6
flutter_secure_storage: ^8.0.0
provider: ^6.0.5
intl: ^0.18.0
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
uses-material-design: true

View File

@@ -1,18 +0,0 @@
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"jsx": "react",
"strict": true,
"paths": {
"@/*": [
"./*"
]
}
},
"include": [
"**/*.ts",
"**/*.tsx",
".expo/types/**/*.ts",
"expo-env.d.ts"
]
}