diff --git a/public/images/btn_bg.png b/public/images/btn_bg.png new file mode 100644 index 0000000..cb8722d Binary files /dev/null and b/public/images/btn_bg.png differ diff --git a/public/images/btn_bg2.png b/public/images/btn_bg2.png new file mode 100644 index 0000000..69128c7 Binary files /dev/null and b/public/images/btn_bg2.png differ diff --git a/src/Helper/CustomAlert.js b/src/Helper/CustomAlert.js index c9da3a6..a9c6ee2 100644 --- a/src/Helper/CustomAlert.js +++ b/src/Helper/CustomAlert.js @@ -12,7 +12,7 @@ const CustomAlert = ({ message, onClose }) => { return ( <> {open && ( - +
{message}
diff --git a/src/Layouts/CameraLayout.js b/src/Layouts/CameraLayout.js index 1ae746d..db54dbb 100644 --- a/src/Layouts/CameraLayout.js +++ b/src/Layouts/CameraLayout.js @@ -53,36 +53,19 @@ function CameraLayout() { return (
- {location.pathname === '/camera' && - - - - } -
+ +
{location.pathname === '/camera' ? <> -
- -
STEP1 : Take Photo
-
- - - + + : @@ -94,7 +77,7 @@ function CameraLayout() {
diff --git a/src/Layouts/RenderLayout.js b/src/Layouts/RenderLayout.js index 8dec3e2..ede5766 100644 --- a/src/Layouts/RenderLayout.js +++ b/src/Layouts/RenderLayout.js @@ -8,45 +8,14 @@ function RenderLayout() { const storedUsername = getUsernameFromCookie(); return (
- - - - -
-
-
- -
- -
STEP2 : Choose a module
-
- - - - -
-
-
- - +
-
- - {/*
diff --git a/src/Page/Camera/FrontPage.js b/src/Page/Camera/FrontPage.js index 47dda49..6b3fd77 100644 --- a/src/Page/Camera/FrontPage.js +++ b/src/Page/Camera/FrontPage.js @@ -1,11 +1,13 @@ -import React,{useEffect,useState} from 'react' +import React,{useEffect,useState,useRef} from 'react' import { Link,useNavigate } from "react-router-dom"; import { motion, AnimatePresence, useAnimation } from "framer-motion"; -import { FaArrowRight } from "react-icons/fa"; -import { Button,Checkbox,Typography,Input } from "@material-tailwind/react"; +import { FaArrowRight,FaUpload } from "react-icons/fa"; +import { Button,Checkbox,Typography,Input,IconButton } from "@material-tailwind/react"; import {useImage} from '../../Helper/ImageContext' import { setUsernameToCookie } from '../../Helper/Helper'; import CustomAlert from "../../Helper/CustomAlert"; +import { FaTimes } from "react-icons/fa"; + function FrontPage({handleClick}) { const navigate = useNavigate(); const [notification, setNotification] = useState(null); @@ -13,23 +15,63 @@ function FrontPage({handleClick}) { // const [isHovered, setHovered] = useState(false) const onChange = ({ target }) => setUsername(target.value); const [isHovered, setIsHovered] = useState(false); - const controls = useAnimation(); - const element1Controls = useAnimation(); - const element2Controls = useAnimation(); const handleMouseEnter = () => { setIsHovered(true); }; const handleMouseLeave = () => { setIsHovered(false); }; - - const handleStart = ()=>{ setNotification(null) setTimeout(()=>{ navigate("/camera"); },800) } + //img file input + const [msg,setMsg] = useState('') + const { setBeforeImage } = useImage(); + const [image, setImage] = useState(null); + const allowedImageTypes = ['image/jpeg', 'image/jpg', 'image/png','image/bmp']; + const inputFileRef = useRef( null ); + const onBtnClick = () => { + setImage(null) + inputFileRef.current.click(); + } + const onFilechange = ( e ) => { + /*Selected files data can be collected here.*/ + const file = e.target.files[0]; + console.log(file) + if (!file) return + if (!allowedImageTypes.includes(file.type)) { + setNotification('Only BMP, JPEG, JPG, and PNG image files are allowed.'); + return; + } + if (file.size > 12 * 1024 * 1024) { + setNotification('File size should be less than 12MB.'); + return; + } + + if (file) { + const reader = new FileReader(); + reader.onload = () => { + // 读取文件并更新选定的图像 + const tempImage = new Image(); + tempImage.src = reader.result; + tempImage.onload = () => { + + setImage(reader.result); + setBeforeImage(reader.result); + }; + }; + setMsg('proceed to the next step..') + reader.readAsDataURL(file); + setTimeout(()=>{ + navigate("/templates"); + },1200) + } + + } + @@ -57,7 +99,7 @@ function FrontPage({handleClick}) { // test() return ( -
+
{notification && ( setNotification(null)} /> )} @@ -75,21 +117,30 @@ function FrontPage({handleClick}) { + card-image + {msg && + {msg} + }
+ + + {image && ( +
+ +
+ Selected +
+
+ setImage(null)}> + + +
+
+ +
+ )}
@@ -124,15 +198,46 @@ function FrontPage({handleClick}) {
-
+
- start +
+
Take photo
+
+
+
or
+
+ +
+
Upload
+
diff --git a/src/Page/Camera/ModelSelect.js b/src/Page/Camera/ModelSelect.js index 01d4df7..2b7036b 100644 --- a/src/Page/Camera/ModelSelect.js +++ b/src/Page/Camera/ModelSelect.js @@ -413,7 +413,7 @@ function ModelSelect() { }; return ( -
+
{beforeImage? @@ -434,48 +434,39 @@ function ModelSelect() { :
Remember to upload a photo
} -
- { - bannerData?.map((item,index)=>{ - return( -
-
-
{ - handleImageClick(index) - setCurrentId(String(index+1)) - }} - > - - -
- -
-
{item.title}
-
{item.subtitle}
-
- -
- -
- ) - }) - } - - - - - + + + + + + + + + +
+ +
+ +
{beforeImage? -
- +
: -
+
No images found for operation.
Please take a new photo or upload the image.
@@ -502,7 +493,6 @@ function ModelSelect() { initial={{ opacity: 0,y:10 }} animate={{ opacity: 1,y:0}} exit={{ opacity: 0,y:10}} src={bannerData[currentIndex].url} alt="Selected" className=" max-w-full h-fulll " /> -
{msg && !msg.includes('Error') && ( diff --git a/src/Page/Camera/ReadyToTake.js b/src/Page/Camera/ReadyToTake.js index 1e66449..4a68f24 100644 --- a/src/Page/Camera/ReadyToTake.js +++ b/src/Page/Camera/ReadyToTake.js @@ -1,6 +1,6 @@ import React, { useState, useRef, useEffect, Suspense,useCallback } from "react"; import {useImage} from '../../Helper/ImageContext' -import { Link } from "react-router-dom"; +import { Link,useNavigate } from "react-router-dom"; import {Camera} from "react-camera-pro"; import Webcam from "react-webcam"; import styled from 'styled-components'; @@ -29,6 +29,7 @@ const ResultImagePreview = styled.div` } `; function ReadyToTake({handleBackClick}) { + const navigate = useNavigate(); const storedUsername = getUsernameFromCookie(); const [isCameraOpen, setCameraOpen] = useState(true); const [selectedImage, setSelectedImage] = useState(null); @@ -49,6 +50,7 @@ function ReadyToTake({handleBackClick}) { const allowedImageTypes = ['image/jpeg', 'image/jpg', 'image/png','image/bmp']; const [ isCameraInfo,setIsCameraInfo] = useState(false) const [isMobile, setIsMobile] = useState(window.innerWidth < 768); + const [msg,setMsg] = useState('') const handleResize = () => { setIsMobile(window.innerWidth < 768); }; @@ -180,6 +182,10 @@ function ReadyToTake({handleBackClick}) { setBeforeImage(reader.result) }; reader.readAsDataURL(compressFiles); + setMsg('proceed to the next step..') + setTimeout(()=>{ + navigate("/templates"); + },1200) } } @@ -378,7 +384,7 @@ function ReadyToTake({handleBackClick}) { const timeoutId = setTimeout(() => { setIsCameraInfo(false); - }, 10000); + }, 8000); return () => { // 在組件卸載時清除 timeout,避免潛在的記憶體洩漏 @@ -390,62 +396,100 @@ function ReadyToTake({handleBackClick}) { const [src, { blur }] = useProgressiveImg(process.env.PUBLIC_URL+'/images/camera_page/tiny.jpeg', ResultImage); return ( -
+
{notification && ( setNotification(null)} /> )} + + + + + + + + + + + + {isCameraOpen ?
-
- +
+ +
Take Photo
+
+ + +
-
-
Please remove accessories such as glasses and hats, and align your face with the reference line
-
- - - {!image && -
- -
- } + +
+
Please remove accessories such as glasses and hats, and align your face with the reference line
+
+ +
- - {image && ( -
- -
- Selected -
-
- setImage(null)}> - - -
-
- -
- )} + {!image && +
+ +
+ } - {isMobile ? : } + {image && ( +
+ {msg && + {msg} + } + +
+ Selected +
+
+ setImage(null)}> + + +
+ +
+ +
+ )} + + + {isMobile ? : } +
{ isMobile ? @@ -465,7 +509,7 @@ function ReadyToTake({handleBackClick}) { @@ -477,9 +521,9 @@ function ReadyToTake({handleBackClick}) { animate={{ opacity: 1 , x: '-50%',y:-0}} exit={{ opacity: 0,x:'-50%',y:-10 }} transition={{ duration: 0.2 }} - className="absolute -bottom-28 md:-bottom-6 left-1/2 -translate-x-1/2 z-10 flex items-center gap-4 w-[80%]"> + className="absolute -bottom-28 md:-bottom-6 left-1/2 -translate-x-1/2 z-10 flex items-center gap-4 w-[80%] ">