109 lines
No EOL
3.8 KiB
TypeScript
109 lines
No EOL
3.8 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { View, TouchableOpacity } from 'react-native';
|
|
import { MyText, tw, BottomDialog, MyTextInput } from 'common-ui';
|
|
import { trpc } from '@/src/trpc-client';
|
|
import MaterialIcons from '@expo/vector-icons/MaterialIcons';
|
|
import { Alert } from 'react-native';
|
|
|
|
interface UserIncidentDialogProps {
|
|
orderId: number;
|
|
userId: number;
|
|
open: boolean;
|
|
onClose: () => void;
|
|
onSuccess?: () => void;
|
|
}
|
|
|
|
export default function UserIncidentDialog({ orderId, userId, open, onClose, onSuccess }: UserIncidentDialogProps) {
|
|
const [adminComment, setAdminComment] = useState('');
|
|
const [negativityScore, setNegativityScore] = useState('');
|
|
|
|
const addIncidentMutation = trpc.admin.user.addUserIncident.useMutation({
|
|
onSuccess: () => {
|
|
Alert.alert('Success', 'Incident added successfully');
|
|
setAdminComment('');
|
|
setNegativityScore('');
|
|
onClose();
|
|
onSuccess?.();
|
|
},
|
|
onError: (error: any) => {
|
|
Alert.alert('Error', error.message || 'Failed to add incident');
|
|
},
|
|
});
|
|
|
|
const handleAddIncident = () => {
|
|
const score = negativityScore ? parseInt(negativityScore) : undefined;
|
|
|
|
if (!adminComment.trim() && !negativityScore) {
|
|
Alert.alert('Error', 'Please enter a comment or negativity score');
|
|
return;
|
|
}
|
|
|
|
addIncidentMutation.mutate({
|
|
userId,
|
|
orderId,
|
|
adminComment: adminComment || undefined,
|
|
negativityScore: score,
|
|
});
|
|
};
|
|
|
|
return (
|
|
<BottomDialog open={open} onClose={onClose}>
|
|
<View style={tw`p-6`}>
|
|
<View style={tw`items-center mb-6`}>
|
|
<View style={tw`w-12 h-12 bg-amber-100 rounded-full items-center justify-center mb-3`}>
|
|
<MaterialIcons name="warning" size={24} color="#D97706" />
|
|
</View>
|
|
<MyText style={tw`text-xl font-bold text-gray-900 text-center`}>
|
|
Add User Incident
|
|
</MyText>
|
|
<MyText style={tw`text-gray-500 text-center mt-2 text-sm leading-5`}>
|
|
Record an incident for this user. This will be visible in their profile.
|
|
</MyText>
|
|
</View>
|
|
|
|
<MyTextInput
|
|
topLabel="Admin Comment"
|
|
value={adminComment}
|
|
onChangeText={setAdminComment}
|
|
placeholder="Enter details about the incident..."
|
|
multiline
|
|
style={tw`h-24`}
|
|
/>
|
|
|
|
<MyTextInput
|
|
topLabel="Negativity Score (Optional)"
|
|
value={negativityScore}
|
|
onChangeText={setNegativityScore}
|
|
placeholder="0"
|
|
keyboardType="numeric"
|
|
style={tw`mt-4`}
|
|
/>
|
|
|
|
<View style={tw`bg-amber-50 p-4 rounded-xl border border-amber-100 mb-6 mt-4 flex-row items-start`}>
|
|
<MaterialIcons name="info-outline" size={20} color="#D97706" style={tw`mt-0.5`} />
|
|
<MyText style={tw`text-sm text-amber-800 ml-2 flex-1 leading-5`}>
|
|
Higher negativity scores indicate more serious incidents (e.g., repeated cancellations, abusive behavior).
|
|
</MyText>
|
|
</View>
|
|
|
|
<View style={tw`flex-row gap-3`}>
|
|
<TouchableOpacity
|
|
style={tw`flex-1 bg-gray-100 py-3.5 rounded-xl items-center`}
|
|
onPress={onClose}
|
|
>
|
|
<MyText style={tw`text-gray-700 font-bold`}>Cancel</MyText>
|
|
</TouchableOpacity>
|
|
<TouchableOpacity
|
|
style={tw`flex-1 bg-amber-500 py-3.5 rounded-xl items-center shadow-sm ${addIncidentMutation.isPending ? 'opacity-50' : ''}`}
|
|
onPress={handleAddIncident}
|
|
disabled={addIncidentMutation.isPending}
|
|
>
|
|
<MyText style={tw`text-white font-bold`}>
|
|
{addIncidentMutation.isPending ? 'Adding...' : 'Add Incident'}
|
|
</MyText>
|
|
</TouchableOpacity>
|
|
</View>
|
|
</View>
|
|
</BottomDialog>
|
|
);
|
|
} |