register1
This commit is contained in:
parent
13b17037c9
commit
fd0a327b13
@ -1,4 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import ArrowLeftIcon from "@mui/icons-material/ArrowLeft";
|
||||||
|
import ArrowRightIcon from "@mui/icons-material/ArrowRight";
|
||||||
import {
|
import {
|
||||||
Dropzone,
|
Dropzone,
|
||||||
FileMosaic,
|
FileMosaic,
|
||||||
@ -13,6 +15,7 @@ const AdvancedDropzone = ({ value, onChange }) => {
|
|||||||
const [extFiles, setExtFiles] = React.useState(value || []);
|
const [extFiles, setExtFiles] = React.useState(value || []);
|
||||||
const [imageSrc, setImageSrc] = React.useState(undefined);
|
const [imageSrc, setImageSrc] = React.useState(undefined);
|
||||||
const [videoSrc, setVideoSrc] = React.useState(undefined);
|
const [videoSrc, setVideoSrc] = React.useState(undefined);
|
||||||
|
const [hoveredId, setHoveredId] = React.useState(null);
|
||||||
|
|
||||||
const updateFiles = (incomingFiles) => {
|
const updateFiles = (incomingFiles) => {
|
||||||
console.log("incoming files", incomingFiles);
|
console.log("incoming files", incomingFiles);
|
||||||
@ -53,6 +56,17 @@ const AdvancedDropzone = ({ value, onChange }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const moveFile = (fromIndex, toIndex) => {
|
||||||
|
setExtFiles((prev) => {
|
||||||
|
if (toIndex < 0 || toIndex >= prev.length) return prev;
|
||||||
|
const updated = [...prev];
|
||||||
|
const [moved] = updated.splice(fromIndex, 1);
|
||||||
|
updated.splice(toIndex, 0, moved);
|
||||||
|
onChange && onChange(updated);
|
||||||
|
return updated;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Dropzone
|
<Dropzone
|
||||||
@ -77,10 +91,19 @@ const AdvancedDropzone = ({ value, onChange }) => {
|
|||||||
uploadButton: {},
|
uploadButton: {},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{extFiles.map((file) => (
|
{extFiles.map((file, index) => (
|
||||||
|
<div
|
||||||
|
key={file.id}
|
||||||
|
style={{
|
||||||
|
position: "relative",
|
||||||
|
display: "inline-block",
|
||||||
|
marginBottom: 12,
|
||||||
|
}}
|
||||||
|
onMouseEnter={() => setHoveredId(file.id)}
|
||||||
|
onMouseLeave={() => setHoveredId(null)}
|
||||||
|
>
|
||||||
<FileMosaic
|
<FileMosaic
|
||||||
{...file}
|
{...file}
|
||||||
key={file.id}
|
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
onSee={handleSee}
|
onSee={handleSee}
|
||||||
onWatch={handleWatch}
|
onWatch={handleWatch}
|
||||||
@ -89,8 +112,94 @@ const AdvancedDropzone = ({ value, onChange }) => {
|
|||||||
resultOnTooltip
|
resultOnTooltip
|
||||||
alwaysActive
|
alwaysActive
|
||||||
preview
|
preview
|
||||||
info
|
info={false}
|
||||||
/>
|
/>
|
||||||
|
{hoveredId === file.id && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
left: 8,
|
||||||
|
right: 8,
|
||||||
|
bottom: 8,
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "center",
|
||||||
|
padding: "6px 8px",
|
||||||
|
borderRadius: 8,
|
||||||
|
background: "rgba(0,0,0,0.5)",
|
||||||
|
pointerEvents: "auto",
|
||||||
|
zIndex: 5,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
moveFile(index, index - 1);
|
||||||
|
}}
|
||||||
|
disabled={index === 0}
|
||||||
|
style={{
|
||||||
|
width: 32,
|
||||||
|
height: 32,
|
||||||
|
borderRadius: "50%",
|
||||||
|
border: "1px solid rgba(255,255,255,0.6)",
|
||||||
|
background: index === 0 ? "rgba(255,255,255,0.4)" : "#fff",
|
||||||
|
cursor: index === 0 ? "not-allowed" : "pointer",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
boxShadow: "0 2px 6px rgba(0,0,0,0.2)",
|
||||||
|
}}
|
||||||
|
aria-label="Move left"
|
||||||
|
>
|
||||||
|
<ArrowLeftIcon fontSize="small" />
|
||||||
|
</button>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 12,
|
||||||
|
opacity: 0.95,
|
||||||
|
maxWidth: 140,
|
||||||
|
overflow: "hidden",
|
||||||
|
textOverflow: "ellipsis",
|
||||||
|
whiteSpace: "nowrap",
|
||||||
|
}}
|
||||||
|
title={file.name}
|
||||||
|
>
|
||||||
|
{file.name}
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
moveFile(index, index + 1);
|
||||||
|
}}
|
||||||
|
disabled={index === extFiles.length - 1}
|
||||||
|
style={{
|
||||||
|
width: 32,
|
||||||
|
height: 32,
|
||||||
|
borderRadius: "50%",
|
||||||
|
border: "1px solid rgba(255,255,255,0.6)",
|
||||||
|
background:
|
||||||
|
index === extFiles.length - 1
|
||||||
|
? "rgba(255,255,255,0.4)"
|
||||||
|
: "#fff",
|
||||||
|
cursor:
|
||||||
|
index === extFiles.length - 1 ? "not-allowed" : "pointer",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
boxShadow: "0 2px 6px rgba(0,0,0,0.2)",
|
||||||
|
}}
|
||||||
|
aria-label="Move right"
|
||||||
|
>
|
||||||
|
<ArrowRightIcon fontSize="small" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
))}
|
))}
|
||||||
</Dropzone>
|
</Dropzone>
|
||||||
|
|
||||||
|
|||||||
@ -13,8 +13,11 @@ import {
|
|||||||
Typography,
|
Typography,
|
||||||
Link,
|
Link,
|
||||||
InputAdornment,
|
InputAdornment,
|
||||||
|
IconButton,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import CheckCircleIcon from "@mui/icons-material/CheckCircle";
|
import CheckCircleIcon from "@mui/icons-material/CheckCircle";
|
||||||
|
import Visibility from "@mui/icons-material/Visibility";
|
||||||
|
import VisibilityOff from "@mui/icons-material/VisibilityOff";
|
||||||
import AdvancedDropzone from "./AdvancedDropzone";
|
import AdvancedDropzone from "./AdvancedDropzone";
|
||||||
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
|
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
@ -44,6 +47,8 @@ const PersonalDetailsForm = ({ onSubmitStep, errors }) => {
|
|||||||
const [otpError, setOtpError] = useState("");
|
const [otpError, setOtpError] = useState("");
|
||||||
const [mobileOtpVerified, setMobileOtpVerified] = useState(false);
|
const [mobileOtpVerified, setMobileOtpVerified] = useState(false);
|
||||||
const [mobileNumberError, setMobileNumberError] = useState("");
|
const [mobileNumberError, setMobileNumberError] = useState("");
|
||||||
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
|
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
|
||||||
const sendOtp = useSendOtp();
|
const sendOtp = useSendOtp();
|
||||||
const verifyOtp = useVerifyOtp();
|
const verifyOtp = useVerifyOtp();
|
||||||
|
|
||||||
@ -102,7 +107,7 @@ const PersonalDetailsForm = ({ onSubmitStep, errors }) => {
|
|||||||
const raw = cityQuery.data;
|
const raw = cityQuery.data;
|
||||||
if (!raw) return [];
|
if (!raw) return [];
|
||||||
if (Array.isArray(raw)) return raw;
|
if (Array.isArray(raw)) return raw;
|
||||||
return raw.city || raw.district || raw.data || [];
|
return raw.subCaste || raw.district || raw.data || [];
|
||||||
}, [cityQuery.data]);
|
}, [cityQuery.data]);
|
||||||
|
|
||||||
const starOptions = useMemo(() => {
|
const starOptions = useMemo(() => {
|
||||||
@ -194,9 +199,10 @@ const PersonalDetailsForm = ({ onSubmitStep, errors }) => {
|
|||||||
const res = await sendOtp.mutateAsync(data.mobileNumber);
|
const res = await sendOtp.mutateAsync(data.mobileNumber);
|
||||||
const successMessage =
|
const successMessage =
|
||||||
res?.message ||
|
res?.message ||
|
||||||
|
res?.otp ||
|
||||||
res?.status ||
|
res?.status ||
|
||||||
"OTP sent successfully";
|
"OTP sent successfully";
|
||||||
toast.success(successMessage);
|
toast.success(successMessage, { position: "top-right" });
|
||||||
setShowOtp(true);
|
setShowOtp(true);
|
||||||
resetOtp();
|
resetOtp();
|
||||||
setMobileOtpVerified(false);
|
setMobileOtpVerified(false);
|
||||||
@ -207,7 +213,7 @@ const PersonalDetailsForm = ({ onSubmitStep, errors }) => {
|
|||||||
error?.response?.data?.otp ||
|
error?.response?.data?.otp ||
|
||||||
error?.message ||
|
error?.message ||
|
||||||
"Failed to send OTP";
|
"Failed to send OTP";
|
||||||
toast.error(message);
|
toast.error(message, { position: "top-right" });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -251,20 +257,21 @@ const PersonalDetailsForm = ({ onSubmitStep, errors }) => {
|
|||||||
});
|
});
|
||||||
const successMessage =
|
const successMessage =
|
||||||
res?.message ||
|
res?.message ||
|
||||||
|
res?.otp ||
|
||||||
res?.status ||
|
res?.status ||
|
||||||
"OTP verified successfully";
|
"OTP verified successfully";
|
||||||
toast.success(successMessage);
|
toast.success(successMessage, { position: "top-right" });
|
||||||
setMobileOtpVerified(true);
|
setMobileOtpVerified(true);
|
||||||
setMobileNumberError("");
|
setMobileNumberError("");
|
||||||
setOtpError("");
|
setOtpError("");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const message =
|
const message =
|
||||||
error?.response?.data?.otp ||
|
|
||||||
error?.response?.data?.message ||
|
error?.response?.data?.message ||
|
||||||
|
error?.response?.data?.otp ||
|
||||||
error?.message ||
|
error?.message ||
|
||||||
"Invalid or expired OTP";
|
"Invalid or expired OTP";
|
||||||
setOtpError(message);
|
setOtpError(message);
|
||||||
toast.error(message);
|
toast.error(message, { position: "top-right" });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -506,7 +513,7 @@ const PersonalDetailsForm = ({ onSubmitStep, errors }) => {
|
|||||||
|
|
||||||
<Typography sx={{ ml: 2, minWidth: 56 }}>
|
<Typography sx={{ ml: 2, minWidth: 56 }}>
|
||||||
{otpTimer > 0 ? (
|
{otpTimer > 0 ? (
|
||||||
formatTimer(otpTimer)
|
` ${formatTimer(otpTimer) } Seconds`
|
||||||
) : (
|
) : (
|
||||||
<Link
|
<Link
|
||||||
component="button"
|
component="button"
|
||||||
@ -520,7 +527,7 @@ const PersonalDetailsForm = ({ onSubmitStep, errors }) => {
|
|||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
{otpError && (
|
{otpError && (
|
||||||
<Typography color="error" variant="caption" sx={{ mt: 1 }}>
|
<Typography color="error" variant="caption" sx={{ mt: "-10px", fontSize:"12px" }}>
|
||||||
{otpError}
|
{otpError}
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
@ -925,13 +932,26 @@ const PersonalDetailsForm = ({ onSubmitStep, errors }) => {
|
|||||||
</label>
|
</label>
|
||||||
<TextField
|
<TextField
|
||||||
fullWidth
|
fullWidth
|
||||||
type="password"
|
type={showPassword ? "text" : "password"}
|
||||||
name="password"
|
name="password"
|
||||||
label="Enter Password"
|
label="Enter Password"
|
||||||
value={data.password}
|
value={data.password}
|
||||||
onChange={(e) => handleChange("password", e.target.value)}
|
onChange={(e) => handleChange("password", e.target.value)}
|
||||||
error={Boolean(errors.password)}
|
error={Boolean(errors.password)}
|
||||||
helperText={errors.password}
|
helperText={errors.password}
|
||||||
|
InputProps={{
|
||||||
|
endAdornment: (
|
||||||
|
<InputAdornment position="end">
|
||||||
|
<IconButton
|
||||||
|
onClick={() => setShowPassword((prev) => !prev)}
|
||||||
|
edge="end"
|
||||||
|
aria-label="toggle password visibility"
|
||||||
|
>
|
||||||
|
{showPassword ? <VisibilityOff /> : <Visibility />}
|
||||||
|
</IconButton>
|
||||||
|
</InputAdornment>
|
||||||
|
),
|
||||||
|
}}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -943,13 +963,26 @@ const PersonalDetailsForm = ({ onSubmitStep, errors }) => {
|
|||||||
</label>
|
</label>
|
||||||
<TextField
|
<TextField
|
||||||
fullWidth
|
fullWidth
|
||||||
type="password"
|
type={showConfirmPassword ? "text" : "password"}
|
||||||
name="confirmPassword"
|
name="confirmPassword"
|
||||||
label="Confirm Password"
|
label="Confirm Password"
|
||||||
value={data.confirmPassword}
|
value={data.confirmPassword}
|
||||||
onChange={(e) => handleChange("confirmPassword", e.target.value)}
|
onChange={(e) => handleChange("confirmPassword", e.target.value)}
|
||||||
error={Boolean(errors.confirmPassword)}
|
error={Boolean(errors.confirmPassword)}
|
||||||
helperText={errors.confirmPassword}
|
helperText={errors.confirmPassword}
|
||||||
|
InputProps={{
|
||||||
|
endAdornment: (
|
||||||
|
<InputAdornment position="end">
|
||||||
|
<IconButton
|
||||||
|
onClick={() => setShowConfirmPassword((prev) => !prev)}
|
||||||
|
edge="end"
|
||||||
|
aria-label="toggle confirm password visibility"
|
||||||
|
>
|
||||||
|
{showConfirmPassword ? <VisibilityOff /> : <Visibility />}
|
||||||
|
</IconButton>
|
||||||
|
</InputAdornment>
|
||||||
|
),
|
||||||
|
}}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -1022,7 +1055,7 @@ const PersonalDetailsForm = ({ onSubmitStep, errors }) => {
|
|||||||
>
|
>
|
||||||
{cityOptions.map((city) => (
|
{cityOptions.map((city) => (
|
||||||
<MenuItem key={city.id} value={city.id}>
|
<MenuItem key={city.id} value={city.id}>
|
||||||
{getOptionLabel(city, "City")}
|
{getOptionLabel(city.district_name, "City")}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user