chore: update
This commit is contained in:
@@ -704,6 +704,30 @@ export interface PointsTier {
|
|||||||
points: number;
|
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 {
|
export interface AppSettings {
|
||||||
penalties_enabled: boolean;
|
penalties_enabled: boolean;
|
||||||
show_amende_score: boolean;
|
show_amende_score: boolean;
|
||||||
@@ -716,6 +740,7 @@ export interface AppSettings {
|
|||||||
points_zipette_tiers: PointsTier[];
|
points_zipette_tiers: PointsTier[];
|
||||||
points_total_tiers: PointsTier[];
|
points_total_tiers: PointsTier[];
|
||||||
referral_enabled: boolean;
|
referral_enabled: boolean;
|
||||||
|
delivery_schedule: DeliverySchedule;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getSettings = async (): Promise<{
|
export const getSettings = async (): Promise<{
|
||||||
|
|||||||
@@ -33,8 +33,6 @@ import type { Product } from "../../api/types";
|
|||||||
import LoadingSpinner from "../../components/ui/LoadingSpinner";
|
import LoadingSpinner from "../../components/ui/LoadingSpinner";
|
||||||
import Card from "../../components/ui/Card";
|
import Card from "../../components/ui/Card";
|
||||||
import Badge from "../../components/ui/Badge";
|
import Badge from "../../components/ui/Badge";
|
||||||
import { getCategoryColor } from "../../utils/constants";
|
|
||||||
|
|
||||||
import AlertModal from "../../components/ui/AlertModal";
|
import AlertModal from "../../components/ui/AlertModal";
|
||||||
import { useAlert } from "../../hooks/useAlert";
|
import { useAlert } from "../../hooks/useAlert";
|
||||||
|
|
||||||
@@ -759,7 +757,7 @@ export default function ProductsScreen() {
|
|||||||
<Text style={styles.name}>{item.name}</Text>
|
<Text style={styles.name}>{item.name}</Text>
|
||||||
<Badge
|
<Badge
|
||||||
label={item.category}
|
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>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -12,13 +12,113 @@ import {
|
|||||||
import { Ionicons } from "@expo/vector-icons";
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
import { spacing, fontSize, borderRadius } from "../../theme";
|
import { spacing, fontSize, borderRadius } from "../../theme";
|
||||||
import { useTheme } from "../../context/ThemeContext";
|
import { useTheme } from "../../context/ThemeContext";
|
||||||
import { getSettings, updateSettings, getCategories } from "../../api/api_admin";
|
import { getSettings, updateSettings, getCategories, DEFAULT_DELIVERY_SCHEDULE } from "../../api/api_admin";
|
||||||
import type { AppSettings, Category, PointsTier } from "../../api/api_admin";
|
import type { AppSettings, Category, PointsTier, DaySchedule, DeliverySchedule } from "../../api/api_admin";
|
||||||
import AlertModal from "../../components/ui/AlertModal";
|
import AlertModal from "../../components/ui/AlertModal";
|
||||||
import { useAlert } from "../../hooks/useAlert";
|
import { useAlert } from "../../hooks/useAlert";
|
||||||
|
|
||||||
type PoolAssignment = "weed" | "zipette" | "total" | "none";
|
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
|
// Composant éditeur de paliers
|
||||||
// ──────────────────────────────────────────────────────────────
|
// ──────────────────────────────────────────────────────────────
|
||||||
@@ -169,6 +269,7 @@ export default function SettingsScreen() {
|
|||||||
points_zipette_tiers: [],
|
points_zipette_tiers: [],
|
||||||
points_total_tiers: [],
|
points_total_tiers: [],
|
||||||
referral_enabled: true,
|
referral_enabled: true,
|
||||||
|
delivery_schedule: DEFAULT_DELIVERY_SCHEDULE,
|
||||||
});
|
});
|
||||||
const [categories, setCategories] = useState<Category[]>([]);
|
const [categories, setCategories] = useState<Category[]>([]);
|
||||||
|
|
||||||
@@ -185,6 +286,7 @@ export default function SettingsScreen() {
|
|||||||
points_categories_zipette: settingsRes.settings.points_categories_zipette ?? [],
|
points_categories_zipette: settingsRes.settings.points_categories_zipette ?? [],
|
||||||
points_categories_total: settingsRes.settings.points_categories_total ?? [],
|
points_categories_total: settingsRes.settings.points_categories_total ?? [],
|
||||||
points_total_tiers: settingsRes.settings.points_total_tiers ?? [],
|
points_total_tiers: settingsRes.settings.points_total_tiers ?? [],
|
||||||
|
delivery_schedule: settingsRes.settings.delivery_schedule ?? DEFAULT_DELIVERY_SCHEDULE,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (categoriesRes) {
|
if (categoriesRes) {
|
||||||
@@ -573,6 +675,14 @@ export default function SettingsScreen() {
|
|||||||
active={!settings.points_separated}
|
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
|
<TouchableOpacity
|
||||||
style={s.saveButton}
|
style={s.saveButton}
|
||||||
onPress={handleSave}
|
onPress={handleSave}
|
||||||
|
|||||||
@@ -34,13 +34,3 @@ export const getStatusColors = (colors: Colors): Record<string, string> => ({
|
|||||||
offline: colors.textMuted,
|
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