chore: add options for alerts
This commit is contained in:
@@ -205,14 +205,14 @@ export const getMyLocation = async (): Promise<{
|
||||
// ALERTES
|
||||
// ============================================
|
||||
|
||||
export const triggerPoliceAlert = async (): Promise<{
|
||||
export const triggerPoliceAlert = async (alertMessage: string): Promise<{
|
||||
success: boolean;
|
||||
alert_id?: number;
|
||||
message?: string;
|
||||
error?: string;
|
||||
}> => {
|
||||
try {
|
||||
const { data } = await apiClient.post(`${API}/alert`);
|
||||
const { data } = await apiClient.post(`${API}/alert`, { message: alertMessage });
|
||||
return {
|
||||
success: true,
|
||||
alert_id: data.alert_id,
|
||||
|
||||
@@ -60,6 +60,7 @@ export interface Alert {
|
||||
id: number;
|
||||
username: string;
|
||||
status: string;
|
||||
message: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,12 @@ export default function AlertsScreen() {
|
||||
fontSize: fontSize.md,
|
||||
fontWeight: "600",
|
||||
},
|
||||
alertMessage: {
|
||||
color: colors.danger,
|
||||
fontSize: fontSize.sm,
|
||||
fontWeight: "600",
|
||||
marginTop: 2,
|
||||
},
|
||||
date: {
|
||||
color: colors.textMuted,
|
||||
fontSize: fontSize.xs,
|
||||
@@ -75,6 +81,9 @@ export default function AlertsScreen() {
|
||||
<Text style={styles.username}>
|
||||
Livreur: {item.username}
|
||||
</Text>
|
||||
{item.message ? (
|
||||
<Text style={styles.alertMessage}>{item.message}</Text>
|
||||
) : null}
|
||||
<Text style={styles.date}>
|
||||
{new Date(item.created_at).toLocaleString("fr-FR")}
|
||||
</Text>
|
||||
|
||||
@@ -56,6 +56,12 @@ export default function AlertsScreen() {
|
||||
fontSize: fontSize.md,
|
||||
fontWeight: "600",
|
||||
},
|
||||
alertMessage: {
|
||||
color: colors.danger,
|
||||
fontSize: fontSize.sm,
|
||||
fontWeight: "600",
|
||||
marginTop: 2,
|
||||
},
|
||||
date: {
|
||||
color: colors.textMuted,
|
||||
fontSize: fontSize.xs,
|
||||
@@ -108,6 +114,9 @@ export default function AlertsScreen() {
|
||||
<Text style={styles.username}>
|
||||
Livreur: {item.username}
|
||||
</Text>
|
||||
{item.message ? (
|
||||
<Text style={styles.alertMessage}>{item.message}</Text>
|
||||
) : null}
|
||||
<Text style={styles.date}>
|
||||
{new Date(item.created_at).toLocaleString("fr-FR")}
|
||||
</Text>
|
||||
|
||||
@@ -25,14 +25,21 @@ import Button from "../../components/ui/Button";
|
||||
import AlertModal from "../../components/ui/AlertModal";
|
||||
import { useAlert } from "../../hooks/useAlert";
|
||||
|
||||
const ALERT_PHRASES = [
|
||||
{ label: "Contrôle de police", icon: "shield-outline" as const },
|
||||
{ label: "Guet-apens", icon: "warning-outline" as const },
|
||||
];
|
||||
|
||||
export default function AlertsScreen() {
|
||||
const { colors } = useTheme();
|
||||
const [alerts, setAlerts] = useState<AlertType[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
const [triggering, setTriggering] = useState(false);
|
||||
const [showPhraseModal, setShowPhraseModal] = useState(false);
|
||||
const [showConfirmModal, setShowConfirmModal] = useState(false);
|
||||
const [showSuccessModal, setShowSuccessModal] = useState(false);
|
||||
const [selectedPhrase, setSelectedPhrase] = useState("");
|
||||
const [successMessage, setSuccessMessage] = useState("");
|
||||
const [pulseAnim] = useState(() => new Animated.Value(1));
|
||||
const { alert: alertModal, showError, hideAlert } = useAlert();
|
||||
@@ -77,10 +84,16 @@ export default function AlertsScreen() {
|
||||
setRefreshing(false);
|
||||
};
|
||||
|
||||
const handleSelectPhrase = (phrase: string) => {
|
||||
setSelectedPhrase(phrase);
|
||||
setShowPhraseModal(false);
|
||||
setShowConfirmModal(true);
|
||||
};
|
||||
|
||||
const handleConfirmTrigger = async () => {
|
||||
setShowConfirmModal(false);
|
||||
setTriggering(true);
|
||||
const res = await triggerPoliceAlert();
|
||||
const res = await triggerPoliceAlert(selectedPhrase);
|
||||
setTriggering(false);
|
||||
if (res.success) {
|
||||
setSuccessMessage(res.message || "Alerte déclenchée avec succès");
|
||||
@@ -113,6 +126,9 @@ export default function AlertsScreen() {
|
||||
}
|
||||
/>
|
||||
<View style={{ flex: 1, marginLeft: spacing.m }}>
|
||||
{item.message ? (
|
||||
<Text style={styles.alertMessage}>{item.message}</Text>
|
||||
) : null}
|
||||
<Text style={styles.date}>
|
||||
{new Date(item.created_at).toLocaleString("fr-FR")}
|
||||
</Text>
|
||||
@@ -142,6 +158,7 @@ export default function AlertsScreen() {
|
||||
StyleSheet.create({
|
||||
container: { flex: 1, backgroundColor: colors.bgPrimary },
|
||||
row: { flexDirection: "row", alignItems: "center" },
|
||||
alertMessage: { color: colors.textPrimary, fontSize: fontSize.md, fontWeight: "600", marginBottom: 2 },
|
||||
date: { color: colors.textMuted, fontSize: fontSize.sm },
|
||||
empty: {
|
||||
color: colors.textMuted,
|
||||
@@ -303,6 +320,21 @@ export default function AlertsScreen() {
|
||||
fontSize: fontSize.md,
|
||||
fontWeight: "700",
|
||||
},
|
||||
phraseBtn: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
gap: spacing.m,
|
||||
paddingVertical: 14,
|
||||
paddingHorizontal: spacing.l,
|
||||
borderRadius: borderRadius.sm,
|
||||
borderWidth: 1,
|
||||
backgroundColor: colors.bgInput,
|
||||
},
|
||||
phraseBtnText: {
|
||||
fontSize: fontSize.md,
|
||||
fontWeight: "600",
|
||||
flex: 1,
|
||||
},
|
||||
}),
|
||||
[colors],
|
||||
);
|
||||
@@ -311,6 +343,50 @@ export default function AlertsScreen() {
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
{/* Phrase selection Modal */}
|
||||
<Modal
|
||||
visible={showPhraseModal}
|
||||
transparent
|
||||
animationType="fade"
|
||||
onRequestClose={() => setShowPhraseModal(false)}
|
||||
>
|
||||
<View style={styles.modalOverlay}>
|
||||
<View style={[styles.modalContent, { borderColor: colors.danger + "40" }]}>
|
||||
<View style={styles.modalIconCircle}>
|
||||
<View style={styles.modalIconInner}>
|
||||
<Ionicons name="warning" size={40} color={colors.white} />
|
||||
</View>
|
||||
</View>
|
||||
<Text style={styles.modalTitle}>Type d'alerte</Text>
|
||||
<Text style={styles.modalMessage}>
|
||||
Sélectionnez la raison de l'alerte.
|
||||
</Text>
|
||||
<View style={{ width: "100%", gap: spacing.m, marginBottom: spacing.l }}>
|
||||
{ALERT_PHRASES.map((p) => (
|
||||
<TouchableOpacity
|
||||
key={p.label}
|
||||
style={[styles.phraseBtn, { borderColor: colors.danger }]}
|
||||
onPress={() => handleSelectPhrase(p.label)}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<Ionicons name={p.icon} size={20} color={colors.danger} />
|
||||
<Text style={[styles.phraseBtnText, { color: colors.textWhite }]}>
|
||||
{p.label}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
<TouchableOpacity
|
||||
style={styles.modalCancelBtn}
|
||||
onPress={() => setShowPhraseModal(false)}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<Text style={styles.modalCancelText}>Annuler</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</Modal>
|
||||
|
||||
{/* Confirmation Modal */}
|
||||
<Modal
|
||||
visible={showConfirmModal}
|
||||
@@ -342,6 +418,11 @@ export default function AlertsScreen() {
|
||||
police. Cette action notifiera immédiatement
|
||||
l'administration.
|
||||
</Text>
|
||||
{selectedPhrase ? (
|
||||
<Text style={[styles.modalWarning, { color: colors.danger, marginBottom: spacing.m }]}>
|
||||
{selectedPhrase}
|
||||
</Text>
|
||||
) : null}
|
||||
<Text style={styles.modalWarning}>
|
||||
Confirmez-vous le déclenchement ?
|
||||
</Text>
|
||||
@@ -417,7 +498,7 @@ export default function AlertsScreen() {
|
||||
<View style={styles.triggerSection}>
|
||||
<Button
|
||||
title={triggering ? "Envoi..." : "Déclencher alerte police"}
|
||||
onPress={() => setShowConfirmModal(true)}
|
||||
onPress={() => setShowPhraseModal(true)}
|
||||
disabled={triggering}
|
||||
style={{ backgroundColor: colors.danger }}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user