chore: add options for alerts
This commit is contained in:
@@ -205,14 +205,14 @@ export const getMyLocation = async (): Promise<{
|
|||||||
// ALERTES
|
// ALERTES
|
||||||
// ============================================
|
// ============================================
|
||||||
|
|
||||||
export const triggerPoliceAlert = async (): Promise<{
|
export const triggerPoliceAlert = async (alertMessage: string): Promise<{
|
||||||
success: boolean;
|
success: boolean;
|
||||||
alert_id?: number;
|
alert_id?: number;
|
||||||
message?: string;
|
message?: string;
|
||||||
error?: string;
|
error?: string;
|
||||||
}> => {
|
}> => {
|
||||||
try {
|
try {
|
||||||
const { data } = await apiClient.post(`${API}/alert`);
|
const { data } = await apiClient.post(`${API}/alert`, { message: alertMessage });
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
alert_id: data.alert_id,
|
alert_id: data.alert_id,
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ export interface Alert {
|
|||||||
id: number;
|
id: number;
|
||||||
username: string;
|
username: string;
|
||||||
status: string;
|
status: string;
|
||||||
|
message: string;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
updated_at: string;
|
updated_at: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,12 @@ export default function AlertsScreen() {
|
|||||||
fontSize: fontSize.md,
|
fontSize: fontSize.md,
|
||||||
fontWeight: "600",
|
fontWeight: "600",
|
||||||
},
|
},
|
||||||
|
alertMessage: {
|
||||||
|
color: colors.danger,
|
||||||
|
fontSize: fontSize.sm,
|
||||||
|
fontWeight: "600",
|
||||||
|
marginTop: 2,
|
||||||
|
},
|
||||||
date: {
|
date: {
|
||||||
color: colors.textMuted,
|
color: colors.textMuted,
|
||||||
fontSize: fontSize.xs,
|
fontSize: fontSize.xs,
|
||||||
@@ -75,6 +81,9 @@ export default function AlertsScreen() {
|
|||||||
<Text style={styles.username}>
|
<Text style={styles.username}>
|
||||||
Livreur: {item.username}
|
Livreur: {item.username}
|
||||||
</Text>
|
</Text>
|
||||||
|
{item.message ? (
|
||||||
|
<Text style={styles.alertMessage}>{item.message}</Text>
|
||||||
|
) : null}
|
||||||
<Text style={styles.date}>
|
<Text style={styles.date}>
|
||||||
{new Date(item.created_at).toLocaleString("fr-FR")}
|
{new Date(item.created_at).toLocaleString("fr-FR")}
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -56,6 +56,12 @@ export default function AlertsScreen() {
|
|||||||
fontSize: fontSize.md,
|
fontSize: fontSize.md,
|
||||||
fontWeight: "600",
|
fontWeight: "600",
|
||||||
},
|
},
|
||||||
|
alertMessage: {
|
||||||
|
color: colors.danger,
|
||||||
|
fontSize: fontSize.sm,
|
||||||
|
fontWeight: "600",
|
||||||
|
marginTop: 2,
|
||||||
|
},
|
||||||
date: {
|
date: {
|
||||||
color: colors.textMuted,
|
color: colors.textMuted,
|
||||||
fontSize: fontSize.xs,
|
fontSize: fontSize.xs,
|
||||||
@@ -108,6 +114,9 @@ export default function AlertsScreen() {
|
|||||||
<Text style={styles.username}>
|
<Text style={styles.username}>
|
||||||
Livreur: {item.username}
|
Livreur: {item.username}
|
||||||
</Text>
|
</Text>
|
||||||
|
{item.message ? (
|
||||||
|
<Text style={styles.alertMessage}>{item.message}</Text>
|
||||||
|
) : null}
|
||||||
<Text style={styles.date}>
|
<Text style={styles.date}>
|
||||||
{new Date(item.created_at).toLocaleString("fr-FR")}
|
{new Date(item.created_at).toLocaleString("fr-FR")}
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -25,14 +25,21 @@ import Button from "../../components/ui/Button";
|
|||||||
import AlertModal from "../../components/ui/AlertModal";
|
import AlertModal from "../../components/ui/AlertModal";
|
||||||
import { useAlert } from "../../hooks/useAlert";
|
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() {
|
export default function AlertsScreen() {
|
||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
const [alerts, setAlerts] = useState<AlertType[]>([]);
|
const [alerts, setAlerts] = useState<AlertType[]>([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [refreshing, setRefreshing] = useState(false);
|
const [refreshing, setRefreshing] = useState(false);
|
||||||
const [triggering, setTriggering] = useState(false);
|
const [triggering, setTriggering] = useState(false);
|
||||||
|
const [showPhraseModal, setShowPhraseModal] = useState(false);
|
||||||
const [showConfirmModal, setShowConfirmModal] = useState(false);
|
const [showConfirmModal, setShowConfirmModal] = useState(false);
|
||||||
const [showSuccessModal, setShowSuccessModal] = useState(false);
|
const [showSuccessModal, setShowSuccessModal] = useState(false);
|
||||||
|
const [selectedPhrase, setSelectedPhrase] = useState("");
|
||||||
const [successMessage, setSuccessMessage] = useState("");
|
const [successMessage, setSuccessMessage] = useState("");
|
||||||
const [pulseAnim] = useState(() => new Animated.Value(1));
|
const [pulseAnim] = useState(() => new Animated.Value(1));
|
||||||
const { alert: alertModal, showError, hideAlert } = useAlert();
|
const { alert: alertModal, showError, hideAlert } = useAlert();
|
||||||
@@ -77,10 +84,16 @@ export default function AlertsScreen() {
|
|||||||
setRefreshing(false);
|
setRefreshing(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSelectPhrase = (phrase: string) => {
|
||||||
|
setSelectedPhrase(phrase);
|
||||||
|
setShowPhraseModal(false);
|
||||||
|
setShowConfirmModal(true);
|
||||||
|
};
|
||||||
|
|
||||||
const handleConfirmTrigger = async () => {
|
const handleConfirmTrigger = async () => {
|
||||||
setShowConfirmModal(false);
|
setShowConfirmModal(false);
|
||||||
setTriggering(true);
|
setTriggering(true);
|
||||||
const res = await triggerPoliceAlert();
|
const res = await triggerPoliceAlert(selectedPhrase);
|
||||||
setTriggering(false);
|
setTriggering(false);
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
setSuccessMessage(res.message || "Alerte déclenchée avec succès");
|
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 }}>
|
<View style={{ flex: 1, marginLeft: spacing.m }}>
|
||||||
|
{item.message ? (
|
||||||
|
<Text style={styles.alertMessage}>{item.message}</Text>
|
||||||
|
) : null}
|
||||||
<Text style={styles.date}>
|
<Text style={styles.date}>
|
||||||
{new Date(item.created_at).toLocaleString("fr-FR")}
|
{new Date(item.created_at).toLocaleString("fr-FR")}
|
||||||
</Text>
|
</Text>
|
||||||
@@ -142,6 +158,7 @@ export default function AlertsScreen() {
|
|||||||
StyleSheet.create({
|
StyleSheet.create({
|
||||||
container: { flex: 1, backgroundColor: colors.bgPrimary },
|
container: { flex: 1, backgroundColor: colors.bgPrimary },
|
||||||
row: { flexDirection: "row", alignItems: "center" },
|
row: { flexDirection: "row", alignItems: "center" },
|
||||||
|
alertMessage: { color: colors.textPrimary, fontSize: fontSize.md, fontWeight: "600", marginBottom: 2 },
|
||||||
date: { color: colors.textMuted, fontSize: fontSize.sm },
|
date: { color: colors.textMuted, fontSize: fontSize.sm },
|
||||||
empty: {
|
empty: {
|
||||||
color: colors.textMuted,
|
color: colors.textMuted,
|
||||||
@@ -303,6 +320,21 @@ export default function AlertsScreen() {
|
|||||||
fontSize: fontSize.md,
|
fontSize: fontSize.md,
|
||||||
fontWeight: "700",
|
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],
|
[colors],
|
||||||
);
|
);
|
||||||
@@ -311,6 +343,50 @@ export default function AlertsScreen() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<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 */}
|
{/* Confirmation Modal */}
|
||||||
<Modal
|
<Modal
|
||||||
visible={showConfirmModal}
|
visible={showConfirmModal}
|
||||||
@@ -342,6 +418,11 @@ export default function AlertsScreen() {
|
|||||||
police. Cette action notifiera immédiatement
|
police. Cette action notifiera immédiatement
|
||||||
l'administration.
|
l'administration.
|
||||||
</Text>
|
</Text>
|
||||||
|
{selectedPhrase ? (
|
||||||
|
<Text style={[styles.modalWarning, { color: colors.danger, marginBottom: spacing.m }]}>
|
||||||
|
{selectedPhrase}
|
||||||
|
</Text>
|
||||||
|
) : null}
|
||||||
<Text style={styles.modalWarning}>
|
<Text style={styles.modalWarning}>
|
||||||
Confirmez-vous le déclenchement ?
|
Confirmez-vous le déclenchement ?
|
||||||
</Text>
|
</Text>
|
||||||
@@ -417,7 +498,7 @@ export default function AlertsScreen() {
|
|||||||
<View style={styles.triggerSection}>
|
<View style={styles.triggerSection}>
|
||||||
<Button
|
<Button
|
||||||
title={triggering ? "Envoi..." : "Déclencher alerte police"}
|
title={triggering ? "Envoi..." : "Déclencher alerte police"}
|
||||||
onPress={() => setShowConfirmModal(true)}
|
onPress={() => setShowPhraseModal(true)}
|
||||||
disabled={triggering}
|
disabled={triggering}
|
||||||
style={{ backgroundColor: colors.danger }}
|
style={{ backgroundColor: colors.danger }}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user