Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat/FE] Motus 최종버전 002 003 세부 운동 정보 모달, 운동 등록하기 페이지를 구현한다. #50

Merged
merged 8 commits into from
Oct 2, 2023
19 changes: 1 addition & 18 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ import AddExercise from "./pages/AddExercise.jsx";
import { ModalProvider } from "./librarys/context.jsx";
import PlayerPage from "./pages/PlayerPage.jsx";
import store from "./redux/store.js";

import { useEffect } from "react";
import { loadToken } from "./librarys/login-api.js";
import { login } from "./redux/userSlice.js";
import ProtectedRoute from "./components/ProtectedRoute.jsx";
import "./App.scss";

Expand All @@ -21,7 +17,7 @@ const Container = styled.div`
const routerList = [
{ path: "/", element: <MainPage /> },
{ path: "/program/:id/play", element: <PlayerPage />, role: 1 },
{ path: "/register", element: <AddExercise />, role: 2 },
{ path: "/register", element: <AddExercise />}
];

routerList.forEach((item) => {
Expand All @@ -35,19 +31,6 @@ routerList.forEach((item) => {
});

function App() {
const dispatch = store.dispatch;

// Login logic
useEffect(() => {
loadToken().then((result) => {
if (!result) {
return;
} else {
dispatch(login(result));
}
});
});

return (
<Provider store={store}>
<ModalProvider>
Expand Down
2 changes: 1 addition & 1 deletion src/App.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#root {
width: 100%;
height: 100vh;
height: 200vh;
margin: 0 auto;
background-color: #1E1E1E;
font-family: "SUIT Variable", sans-serif;
Expand Down
Binary file added src/assets/icons/Page-left.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions src/components/AddHeader.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import styled from "styled-components";
import LogoImage from "../assets/icons/LOGO.png";
import BackButton from "./BackButton";

const HeaderContainer = styled.div`
display: flex;
align-items: center;
margin-bottom:-10px;
`;

const Logo = styled.img`
margin-top: 20px;
margin-left: 420px;
margin-right: 10px;
`;

const Title = styled.h2`
font-size: 36px;
font-weight: bold;
color: #F2F2F2;
margin-left: 10px;
margin-top: 20px;
`;

const ButtonContainer = styled.div`
margin-left: 1125px;
`;

const AddHeader = () => {
return (
<HeaderContainer>
<Logo src={LogoImage} alt="Logo" />
<Title>영상 등록하기</Title>
<ButtonContainer>
<BackButton/>
</ButtonContainer>
</HeaderContainer>
);
};

export default AddHeader;
38 changes: 38 additions & 0 deletions src/components/BackButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import styled from 'styled-components';
import BackIcon from '../assets/icons/Page-left.png';

const BackButtonContainer = styled.button`
width: 210px;
height: 40px;
background-color: #FFFFFF;
border: 1px solid #BBBBBB;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
padding: 0 15px;
margin-top:40px;
margin-bottom: 10px;
margin-left: -580px;
`;

const BackImage = styled.img`
margin-right: 10px;
`;

const BackText = styled.span`
font-size: 14px;
color: #000000;
font-weight: bold;
`;

const BackButton = () => {
return (
<BackButtonContainer>
<BackImage src={BackIcon} alt="Back" />
<BackText>메인페이지로 돌아가기</BackText>
</BackButtonContainer>
);
}

export default BackButton;
44 changes: 32 additions & 12 deletions src/components/ExerciseCard.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Link } from 'react-router-dom';
import styled from 'styled-components';
import PropTypes from 'prop-types';
import {useState} from 'react';
import ExerciseModal from './ExerciseModal';

const CourseCardContainer = styled.div`
width: 360px;
Expand Down Expand Up @@ -59,16 +60,26 @@ const Hash = styled.span`
color: #727272;
`;

const ExerciseCard = ({ id, image, title, tags }) => {
return (
<Link to={`/program/${id}`} style={{ textDecoration: 'none', color: 'inherit' }}>
<CourseCardContainer>
<CourseImage image={image}>
<TimeInfo>
<TimeText>00:00</TimeText>
</TimeInfo>
</CourseImage>
const ExerciseCard = ({ image, title, tags, description }) => {
const [isModalOpen, setIsModalOpen] = useState(false);

const handleCardClick = (e) => {
e.stopPropagation();
setIsModalOpen(true);
}

const handleCloseModal = () => {
setIsModalOpen(false);
};

return (
<>
<CourseCardContainer onClick={handleCardClick}>
<CourseImage image={image}>
<TimeInfo>
<TimeText>00:00</TimeText>
</TimeInfo>
</CourseImage>
<CourseTitle>{title}</CourseTitle>
<div>
{tags && tags.map((tag, index) => (
Expand All @@ -79,14 +90,23 @@ const ExerciseCard = ({ id, image, title, tags }) => {
))}
</div>
</CourseCardContainer>
</Link>
{isModalOpen && (
<ExerciseModal
video={image}
title={title}
description={description}
tags={tags}
onClose={handleCloseModal}
/>
)}
</>
);
};

ExerciseCard.propTypes = {
id: PropTypes.number.isRequired,
image: PropTypes.string,
title: PropTypes.string.isRequired,
description: PropTypes.string.isRequired,
tags: PropTypes.arrayOf(PropTypes.string)
};

Expand Down
2 changes: 1 addition & 1 deletion src/components/ExerciseList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const Container = styled.div`
width: 1200px;
display: flex;
flex-wrap: wrap;
gap: 20px;
gap: 40px;
margin-top: 20px;
margin-left:10px;
`;
Expand Down
123 changes: 123 additions & 0 deletions src/components/ExerciseModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import styled from 'styled-components';

const ModalOverlay = styled.div`
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.75);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
`;

const ModalContainer = styled.div`
width: 700px;
height: 650px;
background-color: #242424;
border-radius: 10px;
padding: 20px;
box-sizing: border-box;
position: relative;
`;

const VideoPlaceholder = styled.div`
width: 630px;
height: 400px;
background-color: #5F5F5F;
margin-bottom: 10px;
`;

const Title = styled.h2`
font-size: 28px;
font-weight: bold;
color: #F2F2F2;
margin-bottom: 10px;
`;

const Description = styled.p`
font-size: 16px;
color: #F2F2F2;
font-weight: 200;
margin-bottom: 20px;
`;

const TagTitle = styled.span`
font-size: 20px;
color: #5F5F5F;
`;

const TagButton = styled.span`
margin-top: 80px;
height: 28px;
padding: 0 10px;
background-color: #242424;
border-radius: 50px;
border: 1px solid #444444;
font-size: 16px;
color: #F2F2F2;
margin-right: 5px;
display: inline-flex;
align-items: center;
margin-left: 10px;
`;

const ButtonGroup = styled.div`
position: absolute;
right: 20px;
bottom: 20px;
`;

const EnrollButton = styled.button`
width: 100px;
height: 40px;
background-color: #6968CC;
color: #F1F1F1;
font-size: 16px;
border-radius: 10px;
border: none;
margin-right: 10px;
`;

const CloseButton = styled.button`
width: 100px;
height: 40px;
background-color: #F2F2F2;
color: #242424;
font-size: 16px;
border-radius: 10px;
border: none;
`;

const Hash = styled.span`
color: #727272;
`;

const ExerciseModal = ({ video, title, description, tags, onClose }) => {
return (
<ModalOverlay>
<ModalContainer>
<VideoPlaceholder></VideoPlaceholder>
<Title>{title}</Title>
<Description>{description}</Description>
<div>
<TagTitle># 관련 태그</TagTitle>
{tags.map((tag, index) => (
<TagButton key={index}>
<Hash>#</Hash>
{tag}
</TagButton>
))}
</div>
<ButtonGroup>
<EnrollButton>수강하기</EnrollButton>
<CloseButton onClick={onClose}>닫기</CloseButton>
</ButtonGroup>
</ModalContainer>
</ModalOverlay>
);
};

export default ExerciseModal ;
Loading