Initial commit

This commit is contained in:
2025-10-04 18:22:24 +03:00
commit 2852c2c054
291 changed files with 38109 additions and 0 deletions

View File

@@ -0,0 +1,110 @@
.productContainer :global(.ant-radio-wrapper:last-child) {
width: 100% !important;
}
.productContainer :global(.ant-radio-label) {
width: 100% !important;
}
/* radio.module.css */
.productContainer :global(.ant-radio-inner) {
width: 24px !important;
height: 24px !important;
border-radius: 30px !important;
}
.productContainer :global(.ant-radio) {
width: 24px !important;
height: 24px !important;
}
.productContainer :global(.ant-radio-checked .ant-radio-inner) {
border-radius: 30px !important;
}
.productContainer :global(.ant-checkbox-wrapper:last-child) {
width: 100% !important;
}
.productContainer :global(.ant-checkbox-label) {
width: 100% !important;
}
/* .productContainer :global(.ant-checkbox-input) {
margin-top: 5px !important;
} */
.productContainer :global(.ant-checkbox-inner) {
border-radius: 40px !important;
}
/* CheckboxGroup.module.css */
.productContainer :global(.ant-checkbox-inner) {
width: 24px !important;
height: 24px !important;
border-radius: 30px !important;
}
.productContainer :global(.ant-checkbox) {
width: 24px !important;
height: 24px !important;
}
.productContainer :global(.ant-checkbox-checked .ant-checkbox-inner) {
border-radius: 30px !important;
}
.services {
width: 100%;
padding: 0 5px;
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 3px;
}
.services :global(.ant-btn) {
padding: 0 11px !important;
}
.serviceButton {
position: relative;
top: 5px;
height: 32px;
color: #99a2ae;
background-color: #f7f7f7;
border: none;
width: 70px !important;
}
.activeServiceButton {
position: relative;
top: 6px;
height: 24px;
border: none;
color: #ffb700;
background-color: rgba(255, 183, 0, 0.12);
width: 70px !important;
}
:global(.darkApp) .services {
color: #ffffff !important;
background-color: #000000 !important;
border: none;
}
:global(.darkApp) .serviceButton {
color: #ffffff !important;
background-color: rgba(42, 42, 42, 0.8) !important;
border: none;
width: 70px !important;
border-radius: 888px;
}
:global(.darkApp) .activeServiceButton {
color: #ffb700 !important;
background-color: rgba(42, 42, 42, 0.8) !important;
border: none;
width: 70px !important;
border-radius: 888px;
}

96
src/pages/otp/page.tsx Normal file
View File

@@ -0,0 +1,96 @@
import { Button, Space, message } from "antd";
import OtpIcon from "components/Icons/otpIcon.tsx";
import OtpInput from "components/OtpInput/OtpInput";
import ProText from "components/ProText";
import ProTitle from "components/ProTitle";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate, useParams } from "react-router-dom";
import { useConfirmOtpMutation, useSendOtpMutation } from "redux/api/auth";
export default function OtpPage() {
const { id } = useParams();
const { t } = useTranslation();
const [sendOtp, { isLoading }] = useSendOtpMutation();
const [confirmOtp, { isLoading: isConfirmLoading }] = useConfirmOtpMutation();
const [otp, setOtp] = useState<string>("");
const handleOtpSave = (otp: string) => {
try {
setOtp(otp);
} catch (error) {
console.error("Failed to parse otp:", error);
}
};
const navigate = useNavigate();
return (
<>
<div
style={{
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
textAlign: "center",
padding: 16,
gap: 24,
height: "92vh",
}}
>
<OtpIcon />
<div>
<ProTitle level={4}>{t("otp.verification")}</ProTitle>
<ProText style={{ color: "#3E3E3E" }}>
{t("otp.enterThe4DigitCodeThatSentToYourPhoneNumber")}
</ProText>
<br />
<ProText style={{ color: "#3E3E3E" }}>
{localStorage.getItem("otp")}
</ProText>
</div>
<div>
<Space size="small">
<OtpInput
length={5}
onComplete={handleOtpSave}
resendOtp={() =>
sendOtp({
phone: localStorage.getItem("userPhone") || "",
})
}
isLoading={isLoading || isConfirmLoading}
/>
</Space>
</div>
<Button
type="primary"
shape="round"
style={{
width: "100%",
height: 48,
marginBottom: 16,
color: "white",
border: "none",
}}
disabled={!otp || otp.length < 5 || isConfirmLoading}
onClick={() => {
confirmOtp({ otp: otp, phone: localStorage.getItem("userPhone") })
.unwrap()
.then((response) => {
localStorage.setItem(
"customer",
JSON.stringify(response.result.customer)
);
localStorage.setItem("token", response.result.access_token);
message.info(t("otp.confirmOTPSuccess"));
navigate(`/${id}/menu`);
});
}}
>
{t("otp.continue")}
</Button>
</div>
</>
);
}

36
src/pages/otp/types.ts Normal file
View File

@@ -0,0 +1,36 @@
export interface ConfirmOTPResponse {
success: boolean;
result: Result;
message: string;
error: any;
}
export interface Result {
access_token: string;
token_type: string;
expires_in: number;
customer: Customer;
}
export interface Customer {
id: number;
username: string;
email: null;
mobilenumber: string;
device_token: null;
password: string;
redeem_point: string;
customer_image: string;
login_taken: string;
device: string;
social_id: string;
otp_number: string;
otp_status: string;
created_datetime: string;
user_uuid: string;
is_deleted: number;
thawani_customer_id: string;
birth_date: null;
gender: string;
country_id: null;
}