Skip to content

Commit

Permalink
feat(mypage.jsx): add drink water button api with spinner
Browse files Browse the repository at this point in the history
  • Loading branch information
junglesub committed Aug 3, 2024
1 parent 4df0dbe commit 2ca64b7
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 13 deletions.
80 changes: 67 additions & 13 deletions src/pages/Mypage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,51 @@ import { nenu, pretendard } from "../styles/fonts";
import GroupOnOffToggle from "../components/Mypage/GroupOnOffToggle";
import LastLog from "../components/Mypage/LastLog";
import AttendanceCheck from "../components/Mypage/AttendanceCheck";
import Spinner from "../styles/Spinner";
import { useFetchBe } from "../tools/api";

function Mypage() {
const resetAuth = useResetRecoilState(authJwtAtom);
const fetchBe = useFetchBe();

const [groupMode, setGroupMode] = useState(false);
const [showRecord, setShowRecord] = useState("init");
const [loading, setLoading] = useState({
bottle: false,
cup: false,
sip: false,
custom: false,
});

const sendWaterDrink = (type) => {
const typeDrink = {
bottle: 500,
cup: 200,
sip: 30,
custom: 1000,
};
if (loading[type]) return;

setLoading((prev) => ({
...prev,
[type]: true,
}));
fetchBe("/userRecord/add", "POST", { amount: typeDrink[type] }).then(
(json) => {
if (json.message !== "Successfully Added") {
alert("Error while adding water");
return;
}
setTimeout(
setLoading((prev) => ({
...prev,
[type]: false,
})),
1500
);
}
);
};

return (
<NewContainerInnerScroll style={{ backgroundColor: "#EDECEB" }}>
Expand Down Expand Up @@ -67,31 +106,35 @@ function Mypage() {
</MainMugArea>

<WaterButtons>
<WaterButton>
<HoverImageSpan>
<WaterButton onClick={() => sendWaterDrink("sip")}>
<HoverImageSpan className={loading.sip ? "disabled" : ""}>
<img src={ImgSip} draggable={false} />
<img className="hover" src={ImgSipHover} draggable={false} />
<Spinner className="spinner" load={true} />
</HoverImageSpan>
<div className="text">한 모금</div>
</WaterButton>
<WaterButton>
<HoverImageSpan>
<WaterButton onClick={() => sendWaterDrink("cup")}>
<HoverImageSpan className={loading.cup ? "disabled" : ""}>
<img src={ImgCup} draggable={false} />
<img className="hover" src={ImgCupHover} draggable={false} />
<Spinner className="spinner" load={true} />
</HoverImageSpan>
<div className="text">한 컵</div>
</WaterButton>
<WaterButton>
<HoverImageSpan>
<WaterButton onClick={() => sendWaterDrink("bottle")}>
<HoverImageSpan className={loading.bottle ? "disabled" : ""}>
<img src={ImgBottle} draggable={false} />
<img className="hover" src={ImgBottleHover} draggable={false} />
<Spinner className="spinner" load={true} />
</HoverImageSpan>
<div className="text">한 병</div>
</WaterButton>
<WaterButton>
<HoverImageSpan>
<WaterButton onClick={() => sendWaterDrink("custom")}>
<HoverImageSpan className={loading.custom ? "disabled" : ""}>
<img src={ImgCustom} draggable={false} />
<img className="hover" src={ImgCustomHover} draggable={false} />
<Spinner className="spinner" load={true} />
</HoverImageSpan>
<div className="text">직접추가</div>
</WaterButton>
Expand Down Expand Up @@ -186,7 +229,8 @@ const LevelBoxIconContent = {
`,
};

const HoverImageSpan = styled.span`
const HoverImageSpan = styled.div`
position: relative;
& {
cursor: pointer;
}
Expand All @@ -195,12 +239,17 @@ const HoverImageSpan = styled.span`
display: none;
}
&:hover .hover {
display: inline;
&:not(.disabled) .spinner {
display: none;
}
&:hover img:not(.hover) {
display: none;
&:not(.disabled):hover {
.hover {
display: inline;
}
img:not(.hover) {
display: none;
}
}
`;

Expand Down Expand Up @@ -233,6 +282,11 @@ const WaterButton = styled.div`
padding: 8px;
${HoverImageSpan} {
display: block;
&.disabled img {
filter: brightness(0) saturate(100%) invert(80%) sepia(0%) saturate(0%)
hue-rotate(153deg) brightness(97%) contrast(90%);
}
}
.text {
/* 한 모금 */
Expand Down
50 changes: 50 additions & 0 deletions src/styles/Spinner.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from "react";
import styled from "styled-components";

function Spinner({ load, ...props }) {
if (!load) return <></>;
return (
<Wrapper {...props}>
<Spin />
</Wrapper>
);
}

export default Spinner;

const Wrapper = styled.div`
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
/* z-index: 99; */
height: 100%;
width: 100%;
padding: 0;
margin: 0;
/* background-color: #007bff;
mix-blend-mode: overlay; */
display: flex;
justify-content: center;
align-items: center;
`;

const Spin = styled.div`
width: 40px;
height: 40px;
border: 4px solid rgba(0, 0, 0, 0.1);
border-top: 4px solid #333;
border-radius: 50%;
animation: spin 1s linear infinite;
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
`;
7 changes: 7 additions & 0 deletions src/tools/api.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { useRecoilValue } from "recoil";
import { serverRootUrl } from "../constants";
import { authJwtAtom } from "../recoil/auth/atoms";

export const fetchBe = (jwtValue, path, method = "GET", body) =>
new Promise((res, rej) => {
Expand All @@ -21,3 +23,8 @@ export const fetchBe = (jwtValue, path, method = "GET", body) =>

.catch((err) => rej(err));
});

export const useFetchBe = () => {
const jwtValue = useRecoilValue(authJwtAtom);
return (path, method = "GET", body) => fetchBe(jwtValue, path, method, body);
};

0 comments on commit 2ca64b7

Please sign in to comment.