163 lines
3.8 KiB
TypeScript
163 lines
3.8 KiB
TypeScript
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'
|
|
import { Ionicons } from '@expo/vector-icons'
|
|
|
|
const SPARTE_COLOR: Record<string, string> = {
|
|
elektro: '#1D4ED8',
|
|
sanit: '#0F766E',
|
|
it: '#4338CA',
|
|
heizung: '#B45309',
|
|
maler: '#15803D',
|
|
info: '#4338CA',
|
|
}
|
|
|
|
function getSparteColor(sparte: string): string {
|
|
const lower = sparte.toLowerCase()
|
|
for (const [key, color] of Object.entries(SPARTE_COLOR)) {
|
|
if (lower.includes(key)) return color
|
|
}
|
|
return '#003B7E'
|
|
}
|
|
|
|
interface StelleCardProps {
|
|
stelle: {
|
|
id: string
|
|
sparte: string
|
|
stellenAnz: number
|
|
verguetung: string | null
|
|
lehrjahr: string | null
|
|
member: { betrieb: string; ort: string }
|
|
org: { name: string }
|
|
}
|
|
onPress: () => void
|
|
}
|
|
|
|
export function StelleCard({ stelle, onPress }: StelleCardProps) {
|
|
const color = getSparteColor(stelle.sparte)
|
|
const initial = stelle.sparte.charAt(0).toUpperCase()
|
|
|
|
return (
|
|
<TouchableOpacity onPress={onPress} style={styles.card} activeOpacity={0.82}>
|
|
<View style={styles.row}>
|
|
<View style={[styles.iconBox, { backgroundColor: `${color}18` }]}>
|
|
<Text style={[styles.iconLetter, { color }]}>{initial}</Text>
|
|
</View>
|
|
|
|
<View style={styles.content}>
|
|
<Text style={styles.company} numberOfLines={1}>
|
|
{stelle.member.betrieb}
|
|
</Text>
|
|
<Text style={styles.sparte}>{stelle.sparte}</Text>
|
|
|
|
<View style={styles.chips}>
|
|
<View style={styles.chipBrand}>
|
|
<Text style={styles.chipBrandText}>
|
|
{stelle.stellenAnz} Stelle{stelle.stellenAnz > 1 ? 'n' : ''}
|
|
</Text>
|
|
</View>
|
|
{stelle.lehrjahr ? (
|
|
<View style={styles.chip}>
|
|
<Text style={styles.chipText}>{stelle.lehrjahr}</Text>
|
|
</View>
|
|
) : null}
|
|
{stelle.verguetung ? (
|
|
<View style={styles.chip}>
|
|
<Text style={styles.chipText}>{stelle.verguetung}</Text>
|
|
</View>
|
|
) : null}
|
|
</View>
|
|
|
|
<View style={styles.locationRow}>
|
|
<Ionicons name="location-outline" size={12} color="#64748B" />
|
|
<Text style={styles.location}>{stelle.member.ort}</Text>
|
|
</View>
|
|
</View>
|
|
|
|
<Ionicons name="chevron-forward" size={16} color="#94A3B8" />
|
|
</View>
|
|
</TouchableOpacity>
|
|
)
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
card: {
|
|
backgroundColor: '#FFFFFF',
|
|
borderRadius: 16,
|
|
borderWidth: 1,
|
|
borderColor: '#E2E8F0',
|
|
padding: 14,
|
|
shadowColor: '#0F172A',
|
|
shadowOffset: { width: 0, height: 1 },
|
|
shadowOpacity: 0.06,
|
|
shadowRadius: 8,
|
|
elevation: 2,
|
|
},
|
|
row: {
|
|
flexDirection: 'row',
|
|
alignItems: 'flex-start',
|
|
gap: 12,
|
|
},
|
|
iconBox: {
|
|
width: 48,
|
|
height: 48,
|
|
borderRadius: 14,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
},
|
|
iconLetter: {
|
|
fontSize: 22,
|
|
fontWeight: '800',
|
|
},
|
|
content: {
|
|
flex: 1,
|
|
gap: 4,
|
|
},
|
|
company: {
|
|
fontSize: 15,
|
|
fontWeight: '700',
|
|
color: '#0F172A',
|
|
letterSpacing: -0.2,
|
|
},
|
|
sparte: {
|
|
fontSize: 12,
|
|
color: '#64748B',
|
|
},
|
|
chips: {
|
|
flexDirection: 'row',
|
|
flexWrap: 'wrap',
|
|
gap: 6,
|
|
marginTop: 4,
|
|
},
|
|
chipBrand: {
|
|
backgroundColor: '#EFF6FF',
|
|
paddingHorizontal: 8,
|
|
paddingVertical: 3,
|
|
borderRadius: 99,
|
|
},
|
|
chipBrandText: {
|
|
fontSize: 11,
|
|
color: '#003B7E',
|
|
fontWeight: '700',
|
|
},
|
|
chip: {
|
|
backgroundColor: '#F1F5F9',
|
|
paddingHorizontal: 8,
|
|
paddingVertical: 3,
|
|
borderRadius: 99,
|
|
},
|
|
chipText: {
|
|
fontSize: 11,
|
|
color: '#475569',
|
|
fontWeight: '500',
|
|
},
|
|
locationRow: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
gap: 4,
|
|
marginTop: 2,
|
|
},
|
|
location: {
|
|
fontSize: 11,
|
|
color: '#64748B',
|
|
},
|
|
})
|