diff --git a/package-lock.json b/package-lock.json index 7c0bf56..659291b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,6 +34,7 @@ "sass-loader": "^13.3.2", "slick-carousel": "^1.8.1", "style-loader": "^3.3.3", + "styled-components": "^6.1.1", "yup": "^1.3.2" }, "optionalDependencies": { @@ -2268,6 +2269,24 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -3336,14 +3355,11 @@ "url": "https://opencollective.com/popperjs" } }, -<<<<<<< HEAD -======= "node_modules/@rcaferati/wac": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@rcaferati/wac/-/wac-1.0.0.tgz", "integrity": "sha512-7dVbzvcfL9o4UnrCaNeoIs7Ri9Ol+OMfpYYCJJV1dfm+5+pVM6DrvFjPzqifd2ACVABpXmwTQKy9KFxNm/7IdA==" }, ->>>>>>> 4718d6351f8e1ff7c5ea1a6f4ab3873f92c03ab4 "node_modules/@react-aria/ssr": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.0.tgz", @@ -3351,20 +3367,6 @@ "dependencies": { "@swc/helpers": "^0.5.0" }, -<<<<<<< HEAD - "engines": { - "node": ">= 12" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" - } - }, - "node_modules/@remix-run/router": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.6.1.tgz", - "integrity": "sha512-YUkWj+xs0oOzBe74OgErsuR3wVn+efrFhXBWrit50kOiED+pvQe2r6MWY0iJMQU/mSVKxvNzL4ZaYvjdX+G7ZA==", -======= ->>>>>>> 4718d6351f8e1ff7c5ea1a6f4ab3873f92c03ab4 "engines": { "node": ">= 12" }, @@ -3428,54 +3430,6 @@ "react": ">=16.14.0" } }, - "node_modules/@restart/hooks": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.11.tgz", - "integrity": "sha512-Ft/ncTULZN6ldGHiF/k5qt72O8JyRMOeg0tApvCni8LkoiEahO+z3TNxfXIVGy890YtWVDvJAl662dVJSJXvMw==", - "dependencies": { - "dequal": "^2.0.3" - }, - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@restart/ui": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz", - "integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==", - "dependencies": { - "@babel/runtime": "^7.21.0", - "@popperjs/core": "^2.11.6", - "@react-aria/ssr": "^3.5.0", - "@restart/hooks": "^0.4.9", - "@types/warning": "^3.0.0", - "dequal": "^2.0.3", - "dom-helpers": "^5.2.0", - "uncontrollable": "^8.0.1", - "warning": "^4.0.3" - }, - "peerDependencies": { - "react": ">=16.14.0", - "react-dom": ">=16.14.0" - } - }, - "node_modules/@restart/ui/node_modules/dom-helpers": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", - "dependencies": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" - } - }, - "node_modules/@restart/ui/node_modules/uncontrollable": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", - "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", - "peerDependencies": { - "react": ">=16.14.0" - } - }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -4128,6 +4082,11 @@ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==" }, + "node_modules/@types/stylis": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.4.tgz", + "integrity": "sha512-36ZrGJ8fgtBr6nwNnuJ9jXIj+bn/pF6UoqmrQT7+Y99+tFFeHHsoR54+194dHdyhPjgbeoNz3Qru0oRt0l6ASQ==" + }, "node_modules/@types/trusted-types": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", @@ -5809,6 +5768,14 @@ "node": ">=6" } }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -6265,6 +6232,14 @@ "postcss": "^8.4" } }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "engines": { + "node": ">=4" + } + }, "node_modules/css-declaration-sorter": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", @@ -6476,6 +6451,16 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, "node_modules/css-tree": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", @@ -9515,14 +9500,11 @@ "loose-envify": "^1.0.0" } }, -<<<<<<< HEAD -======= "node_modules/ip": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" }, ->>>>>>> 4718d6351f8e1ff7c5ea1a6f4ab3873f92c03ab4 "node_modules/ipaddr.js": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", @@ -15300,14 +15282,11 @@ "react": ">=0.14.0" } }, -<<<<<<< HEAD -======= "node_modules/property-expr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==" }, ->>>>>>> 4718d6351f8e1ff7c5ea1a6f4ab3873f92c03ab4 "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -15481,8 +15460,6 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, -<<<<<<< HEAD -======= "node_modules/react-awesome-button": { "version": "7.0.5", "resolved": "https://registry.npmjs.org/react-awesome-button/-/react-awesome-button-7.0.5.tgz", @@ -15491,7 +15468,6 @@ "@rcaferati/wac": "^1.0.0" } }, ->>>>>>> 4718d6351f8e1ff7c5ea1a6f4ab3873f92c03ab4 "node_modules/react-bootstrap": { "version": "2.9.1", "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.9.1.tgz", @@ -16939,6 +16915,11 @@ "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==" }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -17545,6 +17526,33 @@ "webpack": "^5.0.0" } }, + "node_modules/styled-components": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.1.tgz", + "integrity": "sha512-cpZZP5RrKRIClBW5Eby4JM1wElLVP4NQrJbJ0h10TidTyJf4SIIwa3zLXOoPb4gJi8MsJ8mjq5mu2IrEhZIAcQ==", + "dependencies": { + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/unitless": "^0.8.0", + "@types/stylis": "^4.0.2", + "css-to-react-native": "^3.2.0", + "csstype": "^3.1.2", + "postcss": "^8.4.31", + "shallowequal": "^1.1.0", + "stylis": "^4.3.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0" + } + }, "node_modules/stylehacks": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", @@ -17560,6 +17568,11 @@ "postcss": "^8.2.15" } }, + "node_modules/stylis": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.0.tgz", + "integrity": "sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ==" + }, "node_modules/sucrase": { "version": "3.34.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", diff --git a/package.json b/package.json index 974aeea..776758d 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "sass-loader": "^13.3.2", "slick-carousel": "^1.8.1", "style-loader": "^3.3.3", + "styled-components": "^6.1.1", "yup": "^1.3.2" }, "scripts": { diff --git a/src/assets/img/spinner.gif b/src/assets/img/spinner.gif new file mode 100644 index 0000000..b2508bf Binary files /dev/null and b/src/assets/img/spinner.gif differ diff --git a/src/components/Functions/FileUpload.js b/src/components/Functions/FileUpload.js index aa08581..45e3d1f 100644 --- a/src/components/Functions/FileUpload.js +++ b/src/components/Functions/FileUpload.js @@ -8,14 +8,16 @@ const FileUpload = ({ label, onChange }) => { }; const btnStyle = { - background:"#FFCAF8", - border:"1px solid #FFCAF8", + background:"#2ca8ff", + border:"1px solid #2ca8ff", width:"400px", height:"80px", color: "white", fontWeight:1000, - fontSize:"30px" + fontSize:"30px", } + + return ( diff --git a/src/views/examples/FileUploaderPage.js b/src/views/examples/FileUploaderPage.js index 9f11ade..568e1d6 100644 --- a/src/views/examples/FileUploaderPage.js +++ b/src/views/examples/FileUploaderPage.js @@ -2,6 +2,7 @@ import React, {useState} from 'react'; import axios from 'axios'; import FileUpload from 'components/Functions/FileUpload'; import { useNavigate } from 'react-router-dom'; +import LoadingSpinner from 'views/index-sections/LoadingSpinner'; // reactstrap components import { @@ -19,6 +20,9 @@ function FileUploaderPage() { // 페이지 이동을 위한 navigate const navigate = useNavigate(); + // 로딩 스피너 + const [loading, setLoading] = useState(false); + const [URLThumbnail, setURLThumbnail] = useState(); const createImageURL = (fileBlob) => { // createObjectURL 방식 @@ -44,27 +48,57 @@ function FileUploaderPage() { let formData = new FormData(); formData.append('file', uploadImage); formData.append('nickname', nickname); - - axios({ - method:'post', - url: 'http://3.34.182.50:5000/image', - data: formData, + + try { + setLoading(true); + await axios.post('http://3.34.182.50:5000/image', formData, { headers: { 'Content-Type': 'multipart/form-data', }, }) - .then(function(response){ - // 업로드 성공 시 실행할 코드 - console.log('이미지 업로드 성공'); - navigate(`/result`); - }) - .catch(function(error){ - // 업로드 실패 시 실행할 코드 - console.error('이미지 업로드 실패', error); - }); - } else { - console.error('이미지를 선택해주세요.'); + .then(response => { + + // 이미지 url + console.log(response.data.url); + sessionStorage.setItem('imgUrl',response.data.url); + + // 검사 결과 변수 + /* + 0: dry (미세 각질) + 1: greasy (피지 과다) + 2: erythema between hair follicles (모낭 사이 홍반) + 3: dandruff (비듬) + 4: loss (탈모) + 5: erythema pustules (모낭 홍반 농포) + */ + + console.log('미세 각질', response.data.class[0]); + console.log('피지 과다', response.data.class[1]); + console.log('모낭 사이 홍반', response.data.class[2]); + console.log('비듬', response.data.class[3]); + console.log('탈모', response.data.class[4]); + console.log('모낭 홍반 농포', response.data.class[5]); + + sessionStorage.setItem('dry', response.data.class[0]); + sessionStorage.setItem('greasy', response.data.class[1]); + sessionStorage.setItem('erythema_between_hairFollicles', response.data.class[2]); + sessionStorage.setItem('dandruff', response.data.class[3]); + sessionStorage.setItem('loss', response.data.class[4]); + sessionStorage.setItem('erythema_pustules',response.data.class[5]); + + }); + + console.log('이미지 업로드 성공'); + navigate(`/result`); + setLoading(false); + } catch (error) { + console.error('이미지 업로드 실패', error); + } finally { + setLoading(false); } + } else { + console.error('이미지를 선택해주세요.'); + } }; @@ -79,33 +113,82 @@ function FileUploaderPage() { document.body.classList.remove("sidebar-collapse"); }; }, []); + + const imgBox = { + boxShadow: "0 5px 80px 3px #E1E1E1", + borderRadius: "10px", + width: "630px", + height: "450px", + paddingLeft: "30px", + paddingRight: "30px", + paddingBottom: "30px", + paddingTop: "10px", + } + + const explainImg = { + display: "flex", + justifyContent: "space-around", + backgroundColor: "white", + paddingBottom: "10px", + } + return ( <> -
+
-
- - -

나의 두피 상태를 확인해보고 싶다면?
두피 사진을 올려주세요!


+ +

+ 나의 두피 상태를 확인해보고 싶다면?
두피 사진을 올려주세요! +

+
+ +
+ +
+

+ 💡업로드 Tip💡
+

+ +
+ +
+

+ 🙆‍♀️ 이런 고화질 사진일수록 좋아요 +

+ +
+ +
+

+ 🙅‍♀️ 더 높은 화질로 사진 찍어주세요 +

+ +
+ +
+ +
+ +
{URLThumbnail ? ( thumbnail ) : ( "" )}


+ {loading? : ''} +

-
-
+ +
-










-
); } diff --git a/src/views/examples/ResultPage.js b/src/views/examples/ResultPage.js index 7f58a16..0dd8818 100644 --- a/src/views/examples/ResultPage.js +++ b/src/views/examples/ResultPage.js @@ -8,8 +8,6 @@ import { Col, } from "reactstrap"; - - // core components import IndexNavbar from "components/Navbars/IndexNavbar"; import DefaultFooter from "components/Footers/DefaultFooter.js"; @@ -30,18 +28,86 @@ function ResultPage () { // 세션 스토리지에서 nickname 가져오기 const nickname = sessionStorage.getItem('nickname'); + + // 세션 스토리지에서 이미지 URL 가져오기 + const url = sessionStorage.getItem('imgUrl'); + + // 세션 스토리지에서 검사 결과 가져오기 + /* + 0: dry (미세 각질) + 1: greasy (피지 과다) + 2: erythema between hair follicles (모낭 사이 홍반) + 3: dandruff (비듬) + 4: loss (탈모) + 5: erythema pustules (모낭 홍반 농포) + */ + const dry = sessionStorage.getItem('dry'); + const greasy = sessionStorage.getItem('greasy'); + const erythemaBetweenHairFollicles = sessionStorage.getItem('erythema_between_hairFollicles'); + const dandruff = sessionStorage.getItem('dandruff'); + const loss = sessionStorage.getItem('loss'); + const erythemaPustules = sessionStorage.getItem('erythema_pustules'); + + // 현재 날짜 출력하기 + const today = new Date(); + const formattedDate = `${today.getFullYear()}. ${today.getMonth() + 1}. ${today.getDate()}`; + + // 박스 안에 글 넣기 + const imgBox = { + boxShadow: "0 5px 100px 3px #E8E8E8", + borderRadius: "30px", + width: "900px", + height: "900px", + paddingLeft: "30px", + paddingRight: "30px", + paddingBottom: "30px", + paddingTop: "30px", + } + + // 버튼 + const btnStyle = { + background:"#2ca8ff", + border:"1px solid #2ca8ff", + width:"400px", + height:"80px", + color: "white", + fontWeight:1000, + fontSize:"30px", + } + return ( <> -
{/*NavBar 스타일링*/} +
{/*NavBar 스타일링*/}
-

{nickname}님의 두피 검사 결과입니다!

-



+

📈 {nickname}님의 두피 분석 레포트

+

+
+
+

{formattedDate}

+ +
+

{nickname}님의 결과입니다.

+
+
+ 미세 각질: {dry}
+ 피지 과다: {greasy}
+ 모낭 사이 홍반: {erythemaBetweenHairFollicles}
+ 비듬: {dandruff}
+ 탈모: {loss}
+ 모낭 홍반 농포: {erythemaPustules}
+ +
+ +
+
+
+
diff --git a/src/views/index-sections/LoadingSpinner.js b/src/views/index-sections/LoadingSpinner.js new file mode 100644 index 0000000..5bd7f90 --- /dev/null +++ b/src/views/index-sections/LoadingSpinner.js @@ -0,0 +1,35 @@ +import React from 'react'; +import Spinner from "assets/img/spinner.gif"; +import styled from 'styled-components'; + +const LoadingSpinner = (props) => { + + const Background = styled.div` + position: fixed; + width: 100vw; + height: 100vh; + top: 0; + left: 0; + background: #ffffffb7; + z-index: 999; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +`; + +const LoadingText = styled.div` + font: 1rem 'Noto Sans KR'; + text-align: center; +`; + return ( +
+ + loading ... + loading ... + +
+ ); +} + +export default LoadingSpinner;