From 5536adaf7755487c375f735440c5f3fe9d8aa24d Mon Sep 17 00:00:00 2001 From: shay222 Date: Thu, 23 May 2024 23:18:51 -0400 Subject: [PATCH] Shay's Tech Team Challenge Implementation --- src/App.css | 36 ++++++++++ src/App.js | 46 +++++++++++- .../ButtonContainer/ButtonContainer.css | 15 ++++ .../ButtonContainer/ButtonContainer.js | 14 ++++ .../CardContainer/CardContainer.css | 61 ++++++++++++++++ src/components/CardContainer/CardContainer.js | 72 +++++++++++++++++++ src/components/Header/Header.css | 5 ++ src/components/Header/Header.js | 10 +++ 8 files changed, 256 insertions(+), 3 deletions(-) create mode 100644 src/components/ButtonContainer/ButtonContainer.css create mode 100644 src/components/ButtonContainer/ButtonContainer.js create mode 100644 src/components/CardContainer/CardContainer.css create mode 100644 src/components/CardContainer/CardContainer.js create mode 100644 src/components/Header/Header.css create mode 100644 src/components/Header/Header.js diff --git a/src/App.css b/src/App.css index e69de29..8979118 100644 --- a/src/App.css +++ b/src/App.css @@ -0,0 +1,36 @@ +@import url(https://fonts.google.com/share?selection.family=Lilita+One); +body { + font-family: 'Lilita One', cursive; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0; +} + +.app { + font-family: 'Lilita One', cursive; + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + height: 100%; + transition: background-color 0.4s ease; +} + +.title { + font-size: 36px; + margin-bottom: 20px; +} + +.button-container { + margin-bottom: 20px; +} + +.button-container button { + padding: 10px 20px; + margin: 0 10px; + font-size: 16px; + cursor: pointer; +} + diff --git a/src/App.js b/src/App.js index 2375c25..2307455 100644 --- a/src/App.js +++ b/src/App.js @@ -1,12 +1,52 @@ -import React from 'react'; +import React, { useState, useRef, useEffect } from 'react'; import './App.css'; -import data from './members_details.json' +import members from './members_details.json'; +import Header from './components/Header/Header'; +import ButtonContainer from './components/ButtonContainer/ButtonContainer'; +import CardContainer from './components/CardContainer/CardContainer'; + +const colors = [ + '#bf76db', '#7b1aa1', '#ccac2b', '#e0c867', '#deaeeb', '#ded014','#7b1aa1' +]; function App() { + const [currentIndex, setCurrentIndex] = useState(0); + const [bgColor, setBgColor] = useState('#bf76db'); + + const getRandomColor = () => { + return colors[Math.floor(Math.random() * colors.length)]; + }; + return ( -
+
+
+ { + if(currentIndex > 0){ + setCurrentIndex(currentIndex - 1); + setBgColor(getRandomColor()); + } + }} + showNextCard={() => { + if(currentIndex < members.length - 1){ + setCurrentIndex(currentIndex + 1); + setBgColor(getRandomColor()); + } + }} + currentIndex={currentIndex} + totalMembers={members.length} + /> +
); } + + export default App; diff --git a/src/components/ButtonContainer/ButtonContainer.css b/src/components/ButtonContainer/ButtonContainer.css new file mode 100644 index 0000000..eb5ecdb --- /dev/null +++ b/src/components/ButtonContainer/ButtonContainer.css @@ -0,0 +1,15 @@ +@import url(https://fonts.google.com/share?selection.family=Lilita+One); + +.button-container { + margin-bottom: 20px; + font-family: 'Lilita One', cursive; +} + +.button-container button { + padding: 10px 20px; + margin: 0 10px; + font-size: 16px; + cursor: pointer; + border-radius: 5%; + border: none; +} \ No newline at end of file diff --git a/src/components/ButtonContainer/ButtonContainer.js b/src/components/ButtonContainer/ButtonContainer.js new file mode 100644 index 0000000..d18065f --- /dev/null +++ b/src/components/ButtonContainer/ButtonContainer.js @@ -0,0 +1,14 @@ +import React from 'react' +import './ButtonContainer.css' + +const ButtonContainer = ({showPrevCard, showNextCard, currentIndex, totalMembers}) => { + + return ( +
+ + +
+ ) +} + +export default ButtonContainer \ No newline at end of file diff --git a/src/components/CardContainer/CardContainer.css b/src/components/CardContainer/CardContainer.css new file mode 100644 index 0000000..7b088b0 --- /dev/null +++ b/src/components/CardContainer/CardContainer.css @@ -0,0 +1,61 @@ +.card-container { + position: relative; + width: 100vw; + height: 80vh; + perspective: 1000px; + overflow: hidden; +} + +.card { + position: absolute; + width: 50%; + height: 90%; + background-color: #fff; + border-radius: 10px; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; + transition: transform 0.4s ease, box-shadow 0.4s ease; + will-change: transform; +} + +.card img { + /* width: 400px; + height: 400px; */ + max-width: 50%; + height: auto; + border-radius: 50%; + object-fit: cover; + margin-bottom: 10px; + transition: transform 0.4s ease; +} + +.card .name { + font-size: 22px; + font-weight: bold; + transition: transform 0.4s ease; +} + +.card .position { + font-size: 16px; + color: #555; + transition: transform 0.4s ease; +} + +.card:hover { + transform: scale(1.1); + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2); +} + +.card:hover img, +.card:hover .name, +.card:hover .position { + transform: scale(1.1); +} + +.card.active { + z-index: 1; +} diff --git a/src/components/CardContainer/CardContainer.js b/src/components/CardContainer/CardContainer.js new file mode 100644 index 0000000..bd74f31 --- /dev/null +++ b/src/components/CardContainer/CardContainer.js @@ -0,0 +1,72 @@ +import React, { useRef, useEffect } from 'react'; +import './CardContainer.css'; + +const CardContainer = ({members, currentIndex, setCurrentIndex, setBgColor, getRandomColor}) => { + const containerRef = useRef(null); + const startX = useRef(0); + const endX = useRef(0); + + const handleTouchStart = (e) => { + startX.current = e.touches[0].clientX; + }; + + const handleTouchMove = (e) => { + endX.current = e.touches[0].clientX; + }; + + const handleTouchEnd = () => { + if (startX.current - endX.current > 50) { + showNextCard(); + } else if (endX.current - startX.current > 50) { + showPrevCard(); + } + }; + + const showNextCard = () => { + if (currentIndex < members.length - 1) { + setCurrentIndex(currentIndex + 1); + setBgColor(getRandomColor()); + } + }; + + const showPrevCard = () => { + if (currentIndex > 0) { + setCurrentIndex(currentIndex - 1); + setBgColor(getRandomColor()); + } + }; + + useEffect(() => { + const container = containerRef.current; + container.addEventListener('touchstart', handleTouchStart); + container.addEventListener('touchmove', handleTouchMove); + container.addEventListener('touchend', handleTouchEnd); + + return () => { + container.removeEventListener('touchstart', handleTouchStart); + container.removeEventListener('touchmove', handleTouchMove); + container.removeEventListener('touchend', handleTouchEnd); + }; + }, [currentIndex]); + + + return ( +
+ {members.map((member, index) => ( +
+ {member.name} +
{member.name}
+
{member.position}
+
+ ))} +
+ ) +} + +export default CardContainer \ No newline at end of file diff --git a/src/components/Header/Header.css b/src/components/Header/Header.css new file mode 100644 index 0000000..56d3443 --- /dev/null +++ b/src/components/Header/Header.css @@ -0,0 +1,5 @@ +.title { + font-size: 36px; + margin-bottom: 20px; + text-align: center; +} \ No newline at end of file diff --git a/src/components/Header/Header.js b/src/components/Header/Header.js new file mode 100644 index 0000000..e2a2e89 --- /dev/null +++ b/src/components/Header/Header.js @@ -0,0 +1,10 @@ +import React from 'react' +import './Header.css'; + +const Header = () => { + return ( +

Meet Your 2T4 F!rosh Orientation Committee!

+ ) +} + +export default Header \ No newline at end of file