chore: features category

This commit is contained in:
2026-03-07 15:10:18 +01:00
parent f66efee59c
commit dd31473ca1
13 changed files with 433 additions and 62 deletions
+20 -33
View File
@@ -18,7 +18,8 @@ import {
} from "react-native";
import { useNavigation } from "@react-navigation/native";
import type { NativeStackNavigationProp } from "@react-navigation/native-stack";
import { getAllProducts, getProductsByCategory } from "../../api/api";
import { getAllProducts, getProductsByCategory, getCategories } from "../../api/api";
import type { Category } from "../../api/api";
import type { Product } from "../../api/api_types";
import ProductCard from "../../components/ProductCard";
import CategoryPill from "../../components/CategoryPill";
@@ -33,25 +34,14 @@ const logoGrosSemi = require("../../../assets/logo-gros-semi.png");
const { width: SCREEN_WIDTH } = Dimensions.get("window");
const CARD_WIDTH = SCREEN_WIDTH - 48;
const CATEGORIES = [
{ label: "Tous", value: "tous" },
{ label: "Weed&Hash", value: "weed&hash" },
{ label: "Zipette&Co", value: "zipette&co" },
{ label: "Gros&Semi", value: "gros&semi" },
];
const CATEGORY_TITLES: Record<string, string> = {
tous: "Tous les produits",
"weed&hash": "Weed & Hash",
"zipette&co": "Zipette & Co",
"gros&semi": "Gros & Semi",
};
// Les catégories sont chargées dynamiquement depuis l'API
type Nav = NativeStackNavigationProp<ClientStackParamList>;
export default function ProductsScreen() {
const { colors } = useTheme();
const navigation = useNavigation<Nav>();
const [categories, setCategories] = useState<Category[]>([]);
const [products, setProducts] = useState<Product[]>([]);
const [selectedCategory, setSelectedCategory] = useState("tous");
const [loading, setLoading] = useState(true);
@@ -60,6 +50,10 @@ export default function ProductsScreen() {
const carouselRef = useRef<FlatList>(null);
const scaleAnim = useRef(new Animated.Value(1)).current;
useEffect(() => {
getCategories().then(setCategories);
}, []);
useEffect(() => {
const pulse = Animated.loop(
Animated.sequence([
@@ -190,7 +184,7 @@ export default function ProductsScreen() {
return (
<ImageBackground
source={selectedCategory === "gros&semi" ? logoGrosSemi : undefined}
source={undefined}
style={styles.container}
imageStyle={styles.bgImage}
>
@@ -200,19 +194,24 @@ export default function ProductsScreen() {
showsHorizontalScrollIndicator={false}
contentContainerStyle={styles.filters}
>
{CATEGORIES.map((cat) => (
<CategoryPill
label="Tous"
active={selectedCategory === "tous"}
onPress={() => setSelectedCategory("tous")}
/>
{categories.map((cat) => (
<CategoryPill
key={cat.value}
label={cat.label}
active={selectedCategory === cat.value}
onPress={() => setSelectedCategory(cat.value)}
key={cat.id}
label={cat.name}
active={selectedCategory === cat.name}
onPress={() => setSelectedCategory(cat.name)}
/>
))}
</ScrollView>
</View>
<View style={styles.categoryHeader}>
<Text style={styles.categoryTitle}>
{CATEGORY_TITLES[selectedCategory]}
{selectedCategory === "tous" ? "Tous les produits" : selectedCategory}
</Text>
</View>
{error ? (
@@ -258,18 +257,6 @@ export default function ProductsScreen() {
)}
/>
)}
{selectedCategory === "gros&semi" && (
<View style={styles.comingSoonWrapper}>
<Animated.Text
style={[
styles.comingSoonText,
{ transform: [{ scale: scaleAnim }] },
]}
>
Prochainement
</Animated.Text>
</View>
)}
</ImageBackground>
);
}