feat: Implement initial with admin and mobile clients, authentication, data models, and lead generation scripts.

This commit is contained in:
2026-02-19 16:18:34 +01:00
parent c53a71a5f9
commit 5e2d5fb3ae
32 changed files with 2283 additions and 420 deletions

View File

@@ -8,6 +8,7 @@ import { NEWS_KATEGORIE_LABELS } from '@innungsapp/shared/types'
import { useNewsList } from '@/hooks/useNews'
import { useTermineListe } from '@/hooks/useTermine'
import { useNewsReadStore } from '@/store/news.store'
import { trpc } from '@/lib/trpc'
// Helper to truncate text
function getNewsExcerpt(value: string) {
@@ -23,16 +24,18 @@ export default function HomeScreen() {
const { data: newsItems = [] } = useNewsList()
const { data: termine = [] } = useTermineListe(true)
const readIds = useNewsReadStore((s) => s.readIds)
const { data: me } = trpc.members.me.useQuery()
const userName = me?.name ?? ''
const latestNews = newsItems.slice(0, 2)
const upcomingEvents = termine.slice(0, 3)
const unreadCount = newsItems.filter((item) => !(item.isRead || readIds.has(item.id))).length
const QUICK_ACTIONS = [
{ label: 'Mitglieder', icon: 'people', color: '#003B7E', bg: '#E0F2FE', route: '/(app)/members' },
{ label: 'Termine', icon: 'calendar', color: '#B45309', bg: '#FEF3C7', route: '/(app)/termine' },
{ label: 'Stellen', icon: 'briefcase', color: '#059669', bg: '#D1FAE5', route: '/(app)/stellen' },
{ label: 'Profil', icon: 'person', color: '#4F46E5', bg: '#E0E7FF', route: '/(app)/profil' },
{ label: 'Mitglieder', icon: 'people-circle', color: '#2563EB', bg: '#DBEAFE', route: '/(app)/members' },
{ label: 'Termine', icon: 'alarm', color: '#EA580C', bg: '#FFEDD5', route: '/(app)/termine' },
{ label: 'Stellen', icon: 'construct', color: '#0F766E', bg: '#CCFBF1', route: '/(app)/stellen' },
{ label: 'Aktuelles', icon: 'megaphone', color: '#BE185D', bg: '#FCE7F3', route: '/(app)/news' },
]
return (
@@ -53,7 +56,7 @@ export default function HomeScreen() {
</View>
<View>
<Text style={styles.greeting}>Willkommen zurück,</Text>
<Text style={styles.username}>Demo Admin</Text>
<Text style={styles.username}>{userName}</Text>
</View>
</View>
@@ -461,4 +464,3 @@ const styles = StyleSheet.create({
fontWeight: '500',
},
})

View File

@@ -2,7 +2,7 @@ import { View, Text, ScrollView, TouchableOpacity, Alert, StyleSheet } from 'rea
import { SafeAreaView } from 'react-native-safe-area-context'
import { Ionicons } from '@expo/vector-icons'
import { useAuth } from '@/hooks/useAuth'
import { MOCK_MEMBER_ME } from '@/lib/mock-data'
import { trpc } from '@/lib/trpc'
type Item = {
label: string
@@ -20,9 +20,10 @@ const MENU_ITEMS: Item[] = [
export default function ProfilScreen() {
const { signOut } = useAuth()
const member = MOCK_MEMBER_ME
const { data: me } = trpc.members.me.useQuery()
const name = me?.name ?? ''
const initials = member.name
const initials = name
.split(' ')
.slice(0, 2)
.map((chunk) => chunk[0]?.toUpperCase() ?? '')
@@ -42,7 +43,7 @@ export default function ProfilScreen() {
<Ionicons name="settings-outline" size={15} color="#64748B" />
</TouchableOpacity>
</View>
<Text style={styles.name}>{member.name}</Text>
<Text style={styles.name}>{name}</Text>
<Text style={styles.role}>Innungsgeschaeftsfuehrer</Text>
<View style={styles.badgesRow}>
<View style={styles.statusBadge}>