remove gluestackk-ui

This commit is contained in:
Tran Anh Tuan
2025-11-19 14:23:17 +07:00
parent f3cf10e5e6
commit 742d8f6bcc
20 changed files with 1463 additions and 2624 deletions

View File

@@ -8,24 +8,10 @@ import { showErrorToast } from "@/services/toast_service";
import { sosMessage } from "@/utils/sosUtils";
import { MaterialIcons } from "@expo/vector-icons";
import { useEffect, useState } from "react";
import {
FlatList,
ScrollView,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
View,
} from "react-native";
import { Button, ButtonText } from "../ui/gluestack-ui-provider/button";
import {
Modal,
ModalBackdrop,
ModalBody,
ModalContent,
ModalFooter,
ModalHeader,
} from "../ui/gluestack-ui-provider/modal";
import { StyleSheet, Text, TextInput, View } from "react-native";
import IconButton from "../IconButton";
import Select from "../Select";
import Modal from "../ui/modal";
const SosButton = () => {
const [sosData, setSosData] = useState<Model.SosResponse | null>();
@@ -34,17 +20,23 @@ const SosButton = () => {
null
);
const [customMessage, setCustomMessage] = useState("");
const [showDropdown, setShowDropdown] = useState(false);
const [errors, setErrors] = useState<{ [key: string]: string }>({});
const { t } = useI18n();
const sosOptions = [
...sosMessage.map((msg) => ({ ma: msg.ma, moTa: msg.moTa })),
{ ma: 999, moTa: "Khác" },
...sosMessage.map((msg) => ({
ma: msg.ma,
moTa: msg.moTa,
label: msg.moTa,
value: msg.ma,
})),
{ ma: 999, moTa: "Khác", label: "Khác", value: 999 },
];
const getSosData = async () => {
try {
const response = await queryGetSos();
// console.log("SoS ResponseL: ", response);
setSosData(response.data);
} catch (error) {
console.error("Failed to fetch SOS data:", error);
@@ -58,8 +50,6 @@ const SosButton = () => {
const validateForm = () => {
const newErrors: { [key: string]: string } = {};
// Không cần validate sosMessage vì luôn có default value (11)
if (selectedSosMessage === 999 && customMessage.trim() === "") {
newErrors.customMessage = t("home.sos.statusRequired");
}
@@ -69,27 +59,34 @@ const SosButton = () => {
};
const handleConfirmSos = async () => {
if (validateForm()) {
let messageToSend = "";
if (selectedSosMessage === 999) {
messageToSend = customMessage.trim();
} else {
const selectedOption = sosOptions.find(
(opt) => opt.ma === selectedSosMessage
);
messageToSend = selectedOption ? selectedOption.moTa : "";
}
// Gửi dữ liệu đi
setShowConfirmSosDialog(false);
// Reset form
setSelectedSosMessage(null);
setCustomMessage("");
setErrors({});
await sendSosMessage(messageToSend);
if (!validateForm()) {
console.log("Form chưa validate");
return; // Không đóng modal nếu validate fail
}
let messageToSend = "";
if (selectedSosMessage === 999) {
messageToSend = customMessage.trim();
} else {
const selectedOption = sosOptions.find(
(opt) => opt.ma === selectedSosMessage
);
messageToSend = selectedOption ? selectedOption.moTa : "";
}
// Gửi dữ liệu đi
await sendSosMessage(messageToSend);
// Đóng modal và reset form sau khi gửi thành công
setShowConfirmSosDialog(false);
setSelectedSosMessage(null);
setCustomMessage("");
setErrors({});
};
const handleClickButton = async (isActive: boolean) => {
console.log("Is Active: ", isActive);
if (isActive) {
const resp = await queryDeleteSos();
if (resp.status === 200) {
@@ -115,167 +112,91 @@ const SosButton = () => {
return (
<>
<Button
className="shadow-md rounded-full"
size="lg"
action="negative"
<IconButton
icon={<MaterialIcons name="warning" size={20} color="white" />}
type="danger"
size="middle"
onPress={() => handleClickButton(sosData?.active || false)}
style={{ borderRadius: 20 }}
>
<MaterialIcons name="warning" size={15} color="white" />
<ButtonText className="text-center">
{sosData?.active ? t("home.sos.active") : t("home.sos.inactive")}
</ButtonText>
{/* <ButtonSpinner /> */}
{/* <ButtonIcon /> */}
</Button>
{sosData?.active ? t("home.sos.active") : t("home.sos.inactive")}
</IconButton>
<Modal
isOpen={showConfirmSosDialog}
onClose={() => {
open={showConfirmSosDialog}
onCancel={() => {
setShowConfirmSosDialog(false);
setSelectedSosMessage(null);
setCustomMessage("");
setErrors({});
}}
okText={t("home.sos.confirm")}
cancelText={t("home.sos.cancel")}
title={t("home.sos.title")}
centered
onOk={handleConfirmSos}
>
<ModalBackdrop />
<ModalContent>
<ModalHeader className="flex-col gap-0.5 items-center">
<Text
style={{ fontSize: 18, fontWeight: "bold", textAlign: "center" }}
>
{t("home.sos.title")}
</Text>
</ModalHeader>
<ModalBody className="mb-4">
<ScrollView style={{ maxHeight: 400 }}>
{/* Dropdown Nội dung SOS */}
<View style={styles.formGroup}>
<Text style={styles.label}>{t("home.sos.content")}</Text>
<TouchableOpacity
style={[
styles.dropdownButton,
errors.sosMessage ? styles.errorBorder : {},
]}
onPress={() => setShowDropdown(!showDropdown)}
>
<Text
style={[
styles.dropdownButtonText,
!selectedSosMessage && styles.placeholderText,
]}
>
{selectedSosMessage !== null
? sosOptions.find((opt) => opt.ma === selectedSosMessage)
?.moTa || t("home.sos.selectReason")
: t("home.sos.selectReason")}
</Text>
<MaterialIcons
name={showDropdown ? "expand-less" : "expand-more"}
size={20}
color="#666"
/>
</TouchableOpacity>
{errors.sosMessage && (
<Text style={styles.errorText}>{errors.sosMessage}</Text>
)}
</View>
{/* Select Nội dung SOS */}
<View style={styles.formGroup}>
<Text style={styles.label}>{t("home.sos.content")}</Text>
{/* Input Custom Message nếu chọn "Khác" */}
{selectedSosMessage === 999 && (
<View style={styles.formGroup}>
<Text style={styles.label}>{t("home.sos.statusInput")}</Text>
<TextInput
style={[
styles.input,
errors.customMessage ? styles.errorInput : {},
]}
placeholder={t("home.sos.enterStatus")}
placeholderTextColor="#999"
value={customMessage}
onChangeText={(text) => {
setCustomMessage(text);
if (text.trim() !== "") {
setErrors((prev) => {
const newErrors = { ...prev };
delete newErrors.customMessage;
return newErrors;
});
}
}}
multiline
numberOfLines={4}
/>
{errors.customMessage && (
<Text style={styles.errorText}>{errors.customMessage}</Text>
)}
</View>
)}
</ScrollView>
</ModalBody>
<ModalFooter className="flex-row items-start gap-2">
<Button
onPress={handleConfirmSos}
// className="w-1/3"
action="negative"
>
<ButtonText>{t("home.sos.confirm")}</ButtonText>
</Button>
<Button
onPress={() => {
setShowConfirmSosDialog(false);
setSelectedSosMessage(null);
<Select
value={selectedSosMessage ?? undefined}
options={sosOptions}
placeholder={t("home.sos.selectReason")}
onChange={(value) => {
setSelectedSosMessage(value as number);
// Clear custom message nếu chọn khác lý do
if (value !== 999) {
setCustomMessage("");
setErrors({});
}}
// className="w-1/3"
action="secondary"
>
<ButtonText>{t("home.sos.cancel")}</ButtonText>
</Button>
</ModalFooter>
</ModalContent>
</Modal>
}
// Clear error if exists
if (errors.sosMessage) {
setErrors((prev) => {
const newErrors = { ...prev };
delete newErrors.sosMessage;
return newErrors;
});
}
}}
showSearch={false}
style={[errors.sosMessage ? styles.errorBorder : undefined]}
/>
{errors.sosMessage && (
<Text style={styles.errorText}>{errors.sosMessage}</Text>
)}
</View>
{/* Dropdown Modal - Nổi lên */}
{showDropdown && showConfirmSosDialog && (
<Modal isOpen={showDropdown} onClose={() => setShowDropdown(false)}>
<TouchableOpacity
style={styles.dropdownOverlay}
activeOpacity={1}
onPress={() => setShowDropdown(false)}
>
<View style={styles.dropdownModalContainer}>
<FlatList
data={sosOptions}
keyExtractor={(item) => item.ma.toString()}
renderItem={({ item }) => (
<TouchableOpacity
style={styles.dropdownModalItem}
onPress={() => {
setSelectedSosMessage(item.ma);
setShowDropdown(false);
// Clear custom message nếu chọn khác lý do
if (item.ma !== 999) {
setCustomMessage("");
}
}}
>
<Text
style={[
styles.dropdownModalItemText,
selectedSosMessage === item.ma &&
styles.selectedItemText,
]}
>
{item.moTa}
</Text>
</TouchableOpacity>
)}
/>
</View>
</TouchableOpacity>
</Modal>
)}
{/* Input Custom Message nếu chọn "Khác" */}
{selectedSosMessage === 999 && (
<View style={styles.formGroup}>
<Text style={styles.label}>{t("home.sos.statusInput")}</Text>
<TextInput
style={[
styles.input,
errors.customMessage ? styles.errorInput : {},
]}
placeholder={t("home.sos.enterStatus")}
placeholderTextColor="#999"
value={customMessage}
onChangeText={(text) => {
setCustomMessage(text);
if (text.trim() !== "") {
setErrors((prev) => {
const newErrors = { ...prev };
delete newErrors.customMessage;
return newErrors;
});
}
}}
multiline
numberOfLines={4}
/>
{errors.customMessage && (
<Text style={styles.errorText}>{errors.customMessage}</Text>
)}
</View>
)}
</Modal>
</>
);
};
@@ -290,76 +211,9 @@ const styles = StyleSheet.create({
marginBottom: 8,
color: "#333",
},
dropdownButton: {
borderWidth: 1,
borderColor: "#ddd",
borderRadius: 8,
paddingHorizontal: 12,
paddingVertical: 12,
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
backgroundColor: "#fff",
},
errorBorder: {
borderColor: "#ff4444",
},
dropdownButtonText: {
fontSize: 14,
color: "#333",
flex: 1,
},
placeholderText: {
color: "#999",
},
dropdownList: {
borderWidth: 1,
borderColor: "#ddd",
borderRadius: 8,
marginTop: 4,
backgroundColor: "#fff",
overflow: "hidden",
},
dropdownItem: {
paddingHorizontal: 12,
paddingVertical: 12,
borderBottomWidth: 1,
borderBottomColor: "#eee",
},
dropdownItemText: {
fontSize: 14,
color: "#333",
},
dropdownOverlay: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
dropdownModalContainer: {
backgroundColor: "#fff",
borderRadius: 12,
maxHeight: 400,
minWidth: 280,
shadowColor: "#000",
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.3,
shadowRadius: 8,
elevation: 10,
},
dropdownModalItem: {
paddingHorizontal: 16,
paddingVertical: 14,
borderBottomWidth: 1,
borderBottomColor: "#f0f0f0",
},
dropdownModalItemText: {
fontSize: 14,
color: "#333",
},
selectedItemText: {
fontWeight: "600",
color: "#1054C9",
},
input: {
borderWidth: 1,
borderColor: "#ddd",