Yaltopia-Tickets-App/app/company.tsx

167 lines
5.6 KiB
TypeScript

import React, { useState, useEffect } from "react";
import {
View,
ScrollView,
Pressable,
TextInput,
ActivityIndicator,
RefreshControl,
useColorScheme,
} from "react-native";
import { Text } from "@/components/ui/text";
import { Card, CardContent } from "@/components/ui/card";
import { ScreenWrapper } from "@/components/ScreenWrapper";
import { StandardHeader } from "@/components/StandardHeader";
import { ShadowWrapper } from "@/components/ShadowWrapper";
import { useSirouRouter } from "@sirou/react-native";
import { AppRoutes } from "@/lib/routes";
import { Stack } from "expo-router";
import { api } from "@/lib/api";
import {
UserPlus,
Search,
Mail,
Phone,
ChevronRight,
Briefcase,
} from "@/lib/icons";
export default function CompanyScreen() {
const nav = useSirouRouter<AppRoutes>();
const colorScheme = useColorScheme();
const isDark = colorScheme === "dark";
const [workers, setWorkers] = useState<any[]>([]);
const [loading, setLoading] = useState(true);
const [refreshing, setRefreshing] = useState(false);
const [searchQuery, setSearchQuery] = useState("");
const fetchWorkers = async () => {
try {
const response = await api.users.getAll();
setWorkers(response.data || []);
} catch (error) {
console.error("[CompanyScreen] Error fetching workers:", error);
} finally {
setLoading(false);
setRefreshing(false);
}
};
useEffect(() => {
fetchWorkers();
}, []);
const onRefresh = () => {
setRefreshing(true);
fetchWorkers();
};
const filteredWorkers = workers.filter((worker) => {
const name = `${worker.firstName} ${worker.lastName}`.toLowerCase();
const email = (worker.email || "").toLowerCase();
const query = searchQuery.toLowerCase();
return name.includes(query) || email.includes(query);
});
return (
<ScreenWrapper className="bg-background">
<Stack.Screen options={{ headerShown: false }} />
<StandardHeader title="Company" showBack />
<View className="flex-1 px-5 pt-4">
{/* Search Bar */}
<ShadowWrapper level="xs">
<View className="flex-row items-center bg-card rounded-xl px-4 border border-border h-12 mb-6">
<Search size={18} color={isDark ? "#94a3b8" : "#64748b"} />
<TextInput
className="flex-1 ml-3 text-foreground"
placeholder="Search workers..."
placeholderTextColor={isDark ? "#475569" : "#94a3b8"}
value={searchQuery}
onChangeText={setSearchQuery}
/>
</View>
</ShadowWrapper>
{/* Worker List Header */}
<View className="flex-row justify-between items-center mb-4">
<Text variant="h4" className="text-foreground tracking-tight">
Workers ({filteredWorkers.length})
</Text>
</View>
{loading ? (
<View className="flex-1 justify-center items-center">
<ActivityIndicator color="#ea580c" />
</View>
) : (
<ScrollView
showsVerticalScrollIndicator={false}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={onRefresh}
tintColor="#ea580c"
/>
}
contentContainerStyle={{ paddingBottom: 100 }}
>
{filteredWorkers.length > 0 ? (
filteredWorkers.map((worker) => (
<ShadowWrapper key={worker.id} level="xs">
<Card className="mb-3 overflow-hidden rounded-[12px] bg-card border-0">
<CardContent className="flex-row items-center p-4">
<View className="h-12 w-12 rounded-full bg-secondary/50 items-center justify-center mr-4">
<Text className="text-primary font-bold text-lg">
{worker.firstName?.[0]}
{worker.lastName?.[0]}
</Text>
</View>
<View className="flex-1">
<Text className="text-foreground font-bold text-base">
{worker.firstName} {worker.lastName}
</Text>
<View className="flex-row items-center mt-1">
<Text className="text-muted-foreground text-xs bg-secondary px-2 py-0.5 rounded-md uppercase font-bold tracking-widest text-[10px]">
{worker.role || "WORKER"}
</Text>
</View>
</View>
<ChevronRight
size={18}
color={isDark ? "#334155" : "#cbd5e1"}
/>
</CardContent>
</Card>
</ShadowWrapper>
))
) : (
<View className="py-20 items-center">
<Briefcase
size={48}
color={isDark ? "#1e293b" : "#f1f5f9"}
strokeWidth={1}
/>
<Text variant="muted" className="mt-4">
No workers found
</Text>
</View>
)}
</ScrollView>
)}
</View>
{/* Floating Action Button */}
<Pressable
onPress={() => nav.go("user/create")}
className="absolute bottom-8 right-8 h-14 w-14 bg-primary rounded-full items-center justify-center shadow-lg shadow-primary/40"
>
<UserPlus size={24} color="white" strokeWidth={2.5} />
</Pressable>
</ScreenWrapper>
);
}