Skip to content

Commit

Permalink
Feat/헤더 버그 및 푸터 디자인 (#16)
Browse files Browse the repository at this point in the history
* style/header scroll and user image

* feat: number of comments

* feat: club and team info
  • Loading branch information
ComPhyPark authored Jan 13, 2024
1 parent e410e5d commit da9287d
Show file tree
Hide file tree
Showing 11 changed files with 279 additions and 131 deletions.
2 changes: 2 additions & 0 deletions src/assets/djangoLogo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/assets/reactLogo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
94 changes: 47 additions & 47 deletions src/components/Carousel.module.scss
Original file line number Diff line number Diff line change
@@ -1,47 +1,47 @@
@import "../utils/common.module.scss";

.carouselCon {
position: relative;
overflow: hidden;

.carouselContent {
transition: transform 0.8s ease-in-out;
}

.carouselBtnConRight {
position: absolute;
top: 0;
right: 10px;
display: flex;
align-items: center;
height: 100%;
}
.carouselBtnConLeft {
position: absolute;
top: 0;
left: 10px;
display: flex;
align-items: center;
height: 100%;
}
.carouselBtn {
display: flex;
justify-content: center;
align-items: center;
width: 34px;
height: 34px;
border-style: none;
border-radius: 50%;
padding: 0;
background-color: $white;
box-shadow: 0px 0px 8px $light-gray;
color: $medium-gray;
cursor: pointer;
transition: opacity 0.3s ease;
opacity: 0.5;

&:hover {
opacity: 1;
}
}
}
@import "../utils/common.module.scss";

.carouselCon {
position: relative;
overflow: hidden;

.carouselContent {
transition: transform 0.8s ease-in-out;
}

.carouselBtnConRight {
position: absolute;
top: 0;
right: 10px;
display: flex;
align-items: center;
height: 100%;
}
.carouselBtnConLeft {
position: absolute;
top: 0;
left: 10px;
display: flex;
align-items: center;
height: 100%;
}
.carouselBtn {
display: flex;
justify-content: center;
align-items: center;
width: 34px;
height: 34px;
border-style: none;
border-radius: 50%;
padding: 0;
background-color: $white;
box-shadow: 0px 0px 8px $light-gray;
color: $medium-gray;
cursor: pointer;
transition: opacity 0.3s ease;
opacity: 0.5;

&:hover {
opacity: 1;
}
}
}
144 changes: 72 additions & 72 deletions src/components/Carousel.tsx
Original file line number Diff line number Diff line change
@@ -1,72 +1,72 @@
import { ReactNode, useRef, useState } from "react";
import styles from "./Carousel.module.scss";

export function Carousel({ children }: { children: ReactNode }) {
const [isButtonVisible, setIsButtonVisible] = useState(false);
const [translateX, setTranslateX] = useState(0);
const carouselContentRef = useRef<HTMLDivElement>(null);

const scrollWidth = carouselContentRef.current?.scrollWidth;
const carouselWidth = carouselContentRef.current?.clientWidth;

const isLastCarousel =
scrollWidth && carouselWidth
? carouselWidth - translateX === scrollWidth
: false;
const isFirstCarousel = translateX === 0;

function handleRightClick() {
if (scrollWidth && carouselWidth) {
const nextTranslateX =
carouselWidth - translateX < scrollWidth - carouselWidth
? translateX - carouselWidth
: carouselWidth - scrollWidth;
carouselContentRef.current.style.transform = `translateX(${nextTranslateX}px)`;
setTranslateX(nextTranslateX);
}
}
function handleLeftClick() {
if (scrollWidth && carouselWidth) {
const nextTranslateX =
-translateX > carouselWidth ? translateX + carouselWidth : 0;
carouselContentRef.current.style.transform = `translateX(${nextTranslateX}px)`;
setTranslateX(nextTranslateX);
}
}

return (
<div
className={styles.carouselCon}
onMouseEnter={() => {
setIsButtonVisible(true);
}}
onMouseLeave={() => {
setIsButtonVisible(false);
}}
>
<div className={styles.carouselContent} ref={carouselContentRef}>
{children}
</div>
{isButtonVisible && !isLastCarousel && (
<div className={styles.carouselBtnConRight}>
<button className={styles.carouselBtn} onClick={handleRightClick}>
<img
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDEyIDE2Ij4KICAgIDxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPHBhdGggZD0iTTAgMEgxMlYxNkgweiIvPgogICAgICAgIDxwYXRoIGZpbGw9IiMyOTJBMzIiIHN0cm9rZT0iIzI5MkEzMiIgc3Ryb2tlLXdpZHRoPSIuMzUiIGQ9Ik0zLjQyOSAxMy40MDlMNC4zNTQgMTQuMjU4IDEwLjY4IDguNDYgMTEuMTQzIDguMDM2IDQuMzU0IDEuODEzIDMuNDI5IDIuNjYyIDkuMjkxIDguMDM2eiIvPgogICAgPC9nPgo8L3N2Zz4K"
alt=">"
/>
</button>
</div>
)}
{isButtonVisible && !isFirstCarousel && (
<div className={styles.carouselBtnConLeft}>
<button className={styles.carouselBtn} onClick={handleLeftClick}>
<img
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDEyIDE2Ij4KICAgIDxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPHBhdGggZD0iTTAgMEgxMlYxNkgweiIgdHJhbnNmb3JtPSJyb3RhdGUoMTgwIDYgOCkiLz4KICAgICAgICA8cGF0aCBmaWxsPSIjMjkyQTMyIiBzdHJva2U9IiMyOTJBMzIiIHN0cm9rZS13aWR0aD0iLjM1IiBkPSJNMy40MjkgMTMuNDA5TDQuMzU0IDE0LjI1OCAxMC42OCA4LjQ2IDExLjE0MyA4LjAzNiA0LjM1NCAxLjgxMyAzLjQyOSAyLjY2MiA5LjI5MSA4LjAzNnoiIHRyYW5zZm9ybT0icm90YXRlKDE4MCA2IDgpIi8+CiAgICA8L2c+Cjwvc3ZnPgo="
alt="<"
/>
</button>
</div>
)}
</div>
);
}
import { ReactNode, useRef, useState } from "react";
import styles from "./Carousel.module.scss";

export function Carousel({ children }: { children: ReactNode }) {
const [isButtonVisible, setIsButtonVisible] = useState(false);
const [translateX, setTranslateX] = useState(0);
const carouselContentRef = useRef<HTMLDivElement>(null);

const scrollWidth = carouselContentRef.current?.scrollWidth;
const carouselWidth = carouselContentRef.current?.clientWidth;

const isLastCarousel =
scrollWidth && carouselWidth
? carouselWidth - translateX === scrollWidth
: false;
const isFirstCarousel = translateX === 0;

function handleRightClick() {
if (scrollWidth && carouselWidth) {
const nextTranslateX =
carouselWidth - translateX < scrollWidth - carouselWidth
? translateX - carouselWidth
: carouselWidth - scrollWidth;
carouselContentRef.current.style.transform = `translateX(${nextTranslateX}px)`;
setTranslateX(nextTranslateX);
}
}
function handleLeftClick() {
if (scrollWidth && carouselWidth) {
const nextTranslateX =
-translateX > carouselWidth ? translateX + carouselWidth : 0;
carouselContentRef.current.style.transform = `translateX(${nextTranslateX}px)`;
setTranslateX(nextTranslateX);
}
}

return (
<div
className={styles.carouselCon}
onMouseEnter={() => {
setIsButtonVisible(true);
}}
onMouseLeave={() => {
setIsButtonVisible(false);
}}
>
<div className={styles.carouselContent} ref={carouselContentRef}>
{children}
</div>
{isButtonVisible && !isLastCarousel && (
<div className={styles.carouselBtnConRight}>
<button className={styles.carouselBtn} onClick={handleRightClick}>
<img
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDEyIDE2Ij4KICAgIDxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPHBhdGggZD0iTTAgMEgxMlYxNkgweiIvPgogICAgICAgIDxwYXRoIGZpbGw9IiMyOTJBMzIiIHN0cm9rZT0iIzI5MkEzMiIgc3Ryb2tlLXdpZHRoPSIuMzUiIGQ9Ik0zLjQyOSAxMy40MDlMNC4zNTQgMTQuMjU4IDEwLjY4IDguNDYgMTEuMTQzIDguMDM2IDQuMzU0IDEuODEzIDMuNDI5IDIuNjYyIDkuMjkxIDguMDM2eiIvPgogICAgPC9nPgo8L3N2Zz4K"
alt=">"
/>
</button>
</div>
)}
{isButtonVisible && !isFirstCarousel && (
<div className={styles.carouselBtnConLeft}>
<button className={styles.carouselBtn} onClick={handleLeftClick}>
<img
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDEyIDE2Ij4KICAgIDxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPHBhdGggZD0iTTAgMEgxMlYxNkgweiIgdHJhbnNmb3JtPSJyb3RhdGUoMTgwIDYgOCkiLz4KICAgICAgICA8cGF0aCBmaWxsPSIjMjkyQTMyIiBzdHJva2U9IiMyOTJBMzIiIHN0cm9rZS13aWR0aD0iLjM1IiBkPSJNMy40MjkgMTMuNDA5TDQuMzU0IDE0LjI1OCAxMC42OCA4LjQ2IDExLjE0MyA4LjAzNiA0LjM1NCAxLjgxMyAzLjQyOSAyLjY2MiA5LjI5MSA4LjAzNnoiIHRyYW5zZm9ybT0icm90YXRlKDE4MCA2IDgpIi8+CiAgICA8L2c+Cjwvc3ZnPgo="
alt="<"
/>
</button>
</div>
)}
</div>
);
}
81 changes: 81 additions & 0 deletions src/components/Footer.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
footer {
width: 100%;

section {
margin: 0;
}

.commentNumber {
background-color: #101113;
line-height: 62px;
height: 62px;
text-align: center;

span {
margin: 0 auto;
color: #d1d1d2;
font-size: 19px;
font-weight: 500;
letter-spacing: -0.3px;
line-height: 22px;

em {
color: #ff0558;
font-style: normal;
}
}
}

.companyInfo {
padding: 20px 0 38px;
background-color: #1c1d1f;

.companyInfoDiv {
margin: 0 20px;
display: flex;

@media (min-width: 760px) {
margin: 0 3.5%;
}

@media (min-width: 1100px) {
margin: 0 60px;
}

@media (min-width: 1440px) {
margin: 0 auto;
}

.footerLeft {
flex: 1;
font-size: 13px;
font-weight: 400;
letter-spacing: -0.3px;
line-height: 22px;

.clubIntro a {
color: #a5a5a7;
}

.teamInfo {
color: #848485;
margin-top: 13px;
}
}

.footerRight {
margin-top: 35px;
display: flex;

.blank {
width: 8px;
}

img {
width: 24px;
height: 24px;
}
}
}
}
}
40 changes: 35 additions & 5 deletions src/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,39 @@
import styles from "./Footer.module.scss";
import reactLogo from "../assets/reactLogo.svg";
import djangoLogo from "../assets/djangoLogo.svg";

export default function Footer() {
const comments = 999999999;
return (
<div>
<footer>
<h2>지금까지 999,999,999개의 평가가 쌓였어요</h2>
</footer>
</div>
<footer>
<section className={styles.commentNumber}>
<span>
지금까지 <em>{comments.toLocaleString("ko-KR")} 개의</em> 평가가
쌓였어요.
</span>
</section>
<section className={styles.companyInfo}>
<div className={styles.companyInfoDiv}>
<div className={styles.footerLeft}>
<div className={styles.clubIntro}>
<a href="https://wafflestudio.com/">동아리 소개</a>
</div>
<ul className={styles.teamInfo}>
팀 와플피디아 ㅣ 오수현, 박민철, 정우진, 강우진, 백창원, 이규원,
이다은 ㅣ 서울특별시 관악구 관악로 1
</ul>
</div>
<div className={styles.footerRight}>
<a href="https://github.com/wafflestudio21-5/team6-web">
<img src={reactLogo} />
</a>
<div className={styles.blank} />
<a href="https://github.com/wafflestudio21-5/team6-server">
<img src={djangoLogo} />
</a>
</div>
</div>
</section>
</footer>
);
}
11 changes: 11 additions & 0 deletions src/components/Header.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
z-index: 51;
box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.08);
background: #fff;
transition: background-color 200ms ease 0s;

div {
margin: 0 auto;
max-width: $max-screen + 40px;
Expand Down Expand Up @@ -157,6 +159,15 @@
color: rgb(255, 255, 255);
caret-color: rgba(255, 255, 255, 0.7);
}
input::placeholder {
color: rgba(255, 255, 255, 0.7);
}
input::-webkit-input-placeholder {
color: rgba(255, 255, 255, 0.7);
}
input:-ms-input-placeholder {
color: rgba(255, 255, 255, 0.7);
}
}
}

Expand Down
Loading

0 comments on commit da9287d

Please sign in to comment.