chore: update
This commit is contained in:
@@ -704,6 +704,30 @@ export interface PointsTier {
|
||||
points: number;
|
||||
}
|
||||
|
||||
export interface DaySchedule {
|
||||
enabled: boolean;
|
||||
open_time: string; // "09:00"
|
||||
close_time: string; // "20:00"
|
||||
}
|
||||
|
||||
export interface DeliverySchedule {
|
||||
monday: DaySchedule;
|
||||
tuesday: DaySchedule;
|
||||
wednesday: DaySchedule;
|
||||
thursday: DaySchedule;
|
||||
friday: DaySchedule;
|
||||
saturday: DaySchedule;
|
||||
sunday: DaySchedule;
|
||||
}
|
||||
|
||||
export const DEFAULT_DAY: DaySchedule = { enabled: true, open_time: "09:00", close_time: "20:00" };
|
||||
|
||||
export const DEFAULT_DELIVERY_SCHEDULE: DeliverySchedule = {
|
||||
monday: { ...DEFAULT_DAY }, tuesday: { ...DEFAULT_DAY }, wednesday: { ...DEFAULT_DAY },
|
||||
thursday: { ...DEFAULT_DAY }, friday: { ...DEFAULT_DAY },
|
||||
saturday: { ...DEFAULT_DAY }, sunday: { ...DEFAULT_DAY },
|
||||
};
|
||||
|
||||
export interface AppSettings {
|
||||
penalties_enabled: boolean;
|
||||
show_amende_score: boolean;
|
||||
@@ -716,6 +740,7 @@ export interface AppSettings {
|
||||
points_zipette_tiers: PointsTier[];
|
||||
points_total_tiers: PointsTier[];
|
||||
referral_enabled: boolean;
|
||||
delivery_schedule: DeliverySchedule;
|
||||
}
|
||||
|
||||
export const getSettings = async (): Promise<{
|
||||
|
||||
@@ -33,8 +33,6 @@ import type { Product } from "../../api/types";
|
||||
import LoadingSpinner from "../../components/ui/LoadingSpinner";
|
||||
import Card from "../../components/ui/Card";
|
||||
import Badge from "../../components/ui/Badge";
|
||||
import { getCategoryColor } from "../../utils/constants";
|
||||
|
||||
import AlertModal from "../../components/ui/AlertModal";
|
||||
import { useAlert } from "../../hooks/useAlert";
|
||||
|
||||
@@ -759,7 +757,7 @@ export default function ProductsScreen() {
|
||||
<Text style={styles.name}>{item.name}</Text>
|
||||
<Badge
|
||||
label={item.category}
|
||||
color={categories.find(c => c.name === item.category)?.color || getCategoryColor(item.category, colors)}
|
||||
color={categories.find(c => c.name === item.category)?.color || colors.accent}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -12,13 +12,113 @@ import {
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { spacing, fontSize, borderRadius } from "../../theme";
|
||||
import { useTheme } from "../../context/ThemeContext";
|
||||
import { getSettings, updateSettings, getCategories } from "../../api/api_admin";
|
||||
import type { AppSettings, Category, PointsTier } from "../../api/api_admin";
|
||||
import { getSettings, updateSettings, getCategories, DEFAULT_DELIVERY_SCHEDULE } from "../../api/api_admin";
|
||||
import type { AppSettings, Category, PointsTier, DaySchedule, DeliverySchedule } from "../../api/api_admin";
|
||||
import AlertModal from "../../components/ui/AlertModal";
|
||||
import { useAlert } from "../../hooks/useAlert";
|
||||
|
||||
type PoolAssignment = "weed" | "zipette" | "total" | "none";
|
||||
|
||||
const DAYS: { key: keyof DeliverySchedule; label: string }[] = [
|
||||
{ key: "monday", label: "Lundi" },
|
||||
{ key: "tuesday", label: "Mardi" },
|
||||
{ key: "wednesday", label: "Mercredi" },
|
||||
{ key: "thursday", label: "Jeudi" },
|
||||
{ key: "friday", label: "Vendredi" },
|
||||
{ key: "saturday", label: "Samedi" },
|
||||
{ key: "sunday", label: "Dimanche" },
|
||||
];
|
||||
|
||||
function DeliveryScheduleSection({
|
||||
schedule,
|
||||
onChange,
|
||||
colors,
|
||||
s,
|
||||
}: {
|
||||
schedule: DeliverySchedule;
|
||||
onChange: (sched: DeliverySchedule) => void;
|
||||
colors: any;
|
||||
s: any;
|
||||
}) {
|
||||
const updateDay = (key: keyof DeliverySchedule, patch: Partial<DaySchedule>) => {
|
||||
onChange({ ...schedule, [key]: { ...schedule[key], ...patch } });
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={s.section}>
|
||||
<Text style={s.sectionTitle}>Horaires de livraison</Text>
|
||||
<Text style={[s.hint, { paddingTop: spacing.s }]}>
|
||||
Définissez les jours et horaires d'ouverture pour la livraison.
|
||||
</Text>
|
||||
{DAYS.map(({ key, label }, index) => {
|
||||
const day = schedule[key];
|
||||
return (
|
||||
<View
|
||||
key={key}
|
||||
style={[
|
||||
{
|
||||
paddingHorizontal: spacing.l,
|
||||
paddingVertical: spacing.m,
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: colors.border,
|
||||
},
|
||||
index === 0 && { borderTopWidth: 0 },
|
||||
]}
|
||||
>
|
||||
{/* Ligne : jour + toggle */}
|
||||
<View style={{ flexDirection: "row", alignItems: "center", justifyContent: "space-between", marginBottom: day.enabled ? spacing.s : 0 }}>
|
||||
<View style={{ flexDirection: "row", alignItems: "center", gap: spacing.s }}>
|
||||
<View style={{
|
||||
width: 8, height: 8, borderRadius: 4,
|
||||
backgroundColor: day.enabled ? "#10b981" : colors.border,
|
||||
}} />
|
||||
<Text style={[s.rowLabel]}>{label}</Text>
|
||||
</View>
|
||||
<Switch
|
||||
value={day.enabled}
|
||||
onValueChange={(v) => updateDay(key, { enabled: v })}
|
||||
trackColor={{ false: colors.border, true: "#10b981" }}
|
||||
thumbColor="#fff"
|
||||
/>
|
||||
</View>
|
||||
{/* Horaires */}
|
||||
{day.enabled && (
|
||||
<View style={{ flexDirection: "row", alignItems: "center", gap: spacing.s, marginTop: spacing.xs }}>
|
||||
<Text style={s.thresholdSep}>Ouverture</Text>
|
||||
<TextInput
|
||||
style={[s.thresholdInput, { width: 72 }]}
|
||||
value={day.open_time}
|
||||
onChangeText={(v) => updateDay(key, { open_time: v })}
|
||||
placeholder="09:00"
|
||||
placeholderTextColor={colors.textMuted}
|
||||
keyboardType="numbers-and-punctuation"
|
||||
maxLength={5}
|
||||
/>
|
||||
<Text style={s.thresholdSep}>→</Text>
|
||||
<Text style={s.thresholdSep}>Fermeture</Text>
|
||||
<TextInput
|
||||
style={[s.thresholdInput, { width: 72 }]}
|
||||
value={day.close_time}
|
||||
onChangeText={(v) => updateDay(key, { close_time: v })}
|
||||
placeholder="20:00"
|
||||
placeholderTextColor={colors.textMuted}
|
||||
keyboardType="numbers-and-punctuation"
|
||||
maxLength={5}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
{!day.enabled && (
|
||||
<Text style={[s.hint, { paddingHorizontal: 0, paddingBottom: 0, marginTop: spacing.xs }]}>
|
||||
Fermé ce jour
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────────────
|
||||
// Composant éditeur de paliers
|
||||
// ──────────────────────────────────────────────────────────────
|
||||
@@ -169,6 +269,7 @@ export default function SettingsScreen() {
|
||||
points_zipette_tiers: [],
|
||||
points_total_tiers: [],
|
||||
referral_enabled: true,
|
||||
delivery_schedule: DEFAULT_DELIVERY_SCHEDULE,
|
||||
});
|
||||
const [categories, setCategories] = useState<Category[]>([]);
|
||||
|
||||
@@ -185,6 +286,7 @@ export default function SettingsScreen() {
|
||||
points_categories_zipette: settingsRes.settings.points_categories_zipette ?? [],
|
||||
points_categories_total: settingsRes.settings.points_categories_total ?? [],
|
||||
points_total_tiers: settingsRes.settings.points_total_tiers ?? [],
|
||||
delivery_schedule: settingsRes.settings.delivery_schedule ?? DEFAULT_DELIVERY_SCHEDULE,
|
||||
});
|
||||
}
|
||||
if (categoriesRes) {
|
||||
@@ -573,6 +675,14 @@ export default function SettingsScreen() {
|
||||
active={!settings.points_separated}
|
||||
/>
|
||||
|
||||
{/* Horaires de livraison */}
|
||||
<DeliveryScheduleSection
|
||||
schedule={settings.delivery_schedule ?? DEFAULT_DELIVERY_SCHEDULE}
|
||||
onChange={(sched) => setSettings((p) => ({ ...p, delivery_schedule: sched }))}
|
||||
colors={colors}
|
||||
s={s}
|
||||
/>
|
||||
|
||||
<TouchableOpacity
|
||||
style={s.saveButton}
|
||||
onPress={handleSave}
|
||||
|
||||
@@ -34,13 +34,3 @@ export const getStatusColors = (colors: Colors): Record<string, string> => ({
|
||||
offline: colors.textMuted,
|
||||
});
|
||||
|
||||
export const getCategoryColor = (category: string, colors: Colors): string => {
|
||||
const map: Record<string, string> = {
|
||||
"weed&hash": colors.categoryWeedHash,
|
||||
tous: colors.categoryTous,
|
||||
"zipette&co": colors.categoryZipette,
|
||||
"gros&semi": colors.categoryGros,
|
||||
};
|
||||
const key = category?.toLowerCase().trim();
|
||||
return map[key] || colors.accent;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user