86 lines
3.4 KiB
JavaScript
86 lines
3.4 KiB
JavaScript
|
|
"use client";
|
||
|
|
|
||
|
|
import { useTranslation } from "react-i18next";
|
||
|
|
import { fadeInUp } from "../Animation/OwnerPageAnimation";
|
||
|
|
import { handleImageUpload } from "@/app/HelperFunction/UploadImage";
|
||
|
|
import { motion } from "framer-motion";
|
||
|
|
import Image from "next/image";
|
||
|
|
import { Camera, X } from "lucide-react";
|
||
|
|
import { useRef } from "react";
|
||
|
|
|
||
|
|
export default function UploadImage({ idImagePreviews, type, errors, setIdImagePreviews, setIdImages }) {
|
||
|
|
const { t } = useTranslation();
|
||
|
|
const fileInputRef = useRef(null);
|
||
|
|
const currentPreview = idImagePreviews?.[type];
|
||
|
|
const handleRemoveImage = (e) => {
|
||
|
|
e.stopPropagation();
|
||
|
|
setIdImages((prev) => ({ ...prev, [type]: null }));
|
||
|
|
setIdImagePreviews((prev) => ({ ...prev, [type]: "" }));
|
||
|
|
if (fileInputRef.current) {
|
||
|
|
fileInputRef.current.value = "";
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const getLabel = () => {
|
||
|
|
switch (type) {
|
||
|
|
case "front":
|
||
|
|
return t("register.owner.frontIdLabel");
|
||
|
|
case "back":
|
||
|
|
return t("register.owner.backIdLabel");
|
||
|
|
case "license":
|
||
|
|
return t("register.owner.licenseImageLabel");
|
||
|
|
default:
|
||
|
|
return "";
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const getClickText = () => {
|
||
|
|
return type === "license" ? t("register.owner.clickUploadLicense") : t("register.owner.clickUploadImage");
|
||
|
|
};
|
||
|
|
|
||
|
|
const getAltText = () => {
|
||
|
|
switch (type) {
|
||
|
|
case "front":
|
||
|
|
return t("register.uploadFrontAlt");
|
||
|
|
case "back":
|
||
|
|
return t("register.uploadBackAlt");
|
||
|
|
case "license":
|
||
|
|
return t("register.uploadLicenseAlt");
|
||
|
|
default:
|
||
|
|
return "Preview Image";
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
return (
|
||
|
|
<motion.div variants={fadeInUp} key={`${type}-upload-step`}>
|
||
|
|
<label className="block text-sm font-medium text-gray-300 mb-2">
|
||
|
|
{getLabel()} {type === "license" ? <span className="text-gray-400">({t("register.optional")})</span> : <span className="text-red-500">*</span>}
|
||
|
|
</label>
|
||
|
|
{type === "license" && <div className="mb-2 text-xs text-gray-400">{t("register.owner.licenseHint")}</div>}
|
||
|
|
<div
|
||
|
|
onClick={() => fileInputRef.current?.click()}
|
||
|
|
className={`relative border-2 border-dashed rounded-xl p-6 text-center cursor-pointer transition-all ${
|
||
|
|
currentPreview ? "border-green-500 bg-green-500/10" : errors ? "border-red-500 bg-red-500/10" : "border-gray-700 hover:border-amber-500 hover:bg-white/5"
|
||
|
|
}`}
|
||
|
|
>
|
||
|
|
<input ref={fileInputRef} type="file" accept="image/*" onChange={(e) => handleImageUpload(type, e.target.files?.[0], t, setIdImagePreviews, setIdImages)} className="hidden" />
|
||
|
|
{currentPreview ? (
|
||
|
|
<div className="relative">
|
||
|
|
<Image src={currentPreview} alt={getAltText()} width={200} height={120} className="mx-auto rounded-lg object-cover" />
|
||
|
|
<button type="button" onClick={handleRemoveImage} className="absolute -top-2 -right-2 w-6 h-6 bg-red-500 rounded-full flex items-center justify-center hover:bg-red-600 transition-colors">
|
||
|
|
<X className="w-4 h-4 text-white" />
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
) : (
|
||
|
|
<>
|
||
|
|
<Camera className="w-12 h-12 text-gray-500 mx-auto mb-3" />
|
||
|
|
<p className="text-gray-400">{getClickText()}</p>
|
||
|
|
<p className="text-xs text-gray-500 mt-2">JPEG, PNG, JPG • {t("register.upTo5MB")}</p>
|
||
|
|
</>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
{errors && <p className="text-red-500 text-sm mt-1">{errors}</p>}
|
||
|
|
</motion.div>
|
||
|
|
);
|
||
|
|
}
|