diff --git a/src/assets/images/dice-empty.png b/public/img/dice-empty.png similarity index 100% rename from src/assets/images/dice-empty.png rename to public/img/dice-empty.png diff --git a/src/assets/images/dice1.png b/public/img/dice1.png similarity index 100% rename from src/assets/images/dice1.png rename to public/img/dice1.png diff --git a/src/assets/images/dice2.png b/public/img/dice2.png similarity index 100% rename from src/assets/images/dice2.png rename to public/img/dice2.png diff --git a/src/assets/images/dice3.png b/public/img/dice3.png similarity index 100% rename from src/assets/images/dice3.png rename to public/img/dice3.png diff --git a/src/assets/images/dice4.png b/public/img/dice4.png similarity index 100% rename from src/assets/images/dice4.png rename to public/img/dice4.png diff --git a/src/assets/images/dice5.png b/public/img/dice5.png similarity index 100% rename from src/assets/images/dice5.png rename to public/img/dice5.png diff --git a/src/assets/images/dice6.png b/public/img/dice6.png similarity index 100% rename from src/assets/images/dice6.png rename to public/img/dice6.png diff --git a/public/img/mastercard.png b/public/img/mastercard.png new file mode 100644 index 0000000..8f5ddb0 Binary files /dev/null and b/public/img/mastercard.png differ diff --git a/public/img/visa.png b/public/img/visa.png new file mode 100644 index 0000000..3bac7e3 Binary files /dev/null and b/public/img/visa.png differ diff --git a/src/App.css b/src/App.css index 74b5e05..5edb228 100644 --- a/src/App.css +++ b/src/App.css @@ -36,3 +36,18 @@ transform: rotate(360deg); } } + +.credit-card-container { + display: flex; + justify-content: center; /* Center the cards horizontally */ + gap: 20px; /* Optional: Add space between the cards */ + margin-top: 20px; /* Optional: Add some space above the card container */ +} + +.driver-cards { + text-align: center; +} + +.rgb-color-picker-container { + text-align: center; +} \ No newline at end of file diff --git a/src/App.js b/src/App.js index 3784575..8bf6afe 100644 --- a/src/App.js +++ b/src/App.js @@ -1,25 +1,139 @@ -import logo from './logo.svg'; -import './App.css'; + import './App.css'; + import IdCard from './components/IdCard'; + import Greetings from './components/Greetings'; + import Random from './components/Random'; + import BoxColor from './components/BoxColor'; + import CreditCard from './components/CreditCard'; + import Rating from './components/Rating'; + import DriverCard from './components/DriverCard'; + import LikeButton from './components/LikeButton'; + import ClickablePicture from './components/ClickablePicture'; + import maxence from './assets/images/maxence.png'; + import maxenceGlasses from './assets/images/maxence-glasses.png'; + import Dice from './components/Dice'; + import Carousel from './components/Carousel'; + import NumbersTable from './components/NumbersTable'; + import RGBColorPicker from './components/RGBColorPicker'; // Import the RGBColorPicker -function App() { - return ( -
-
- logo -

- Edit src/App.js and save to reload. -

- - Learn React - -
-
- ); -} -export default App; + function App() { + return ( +
+
+ + +
+
+ Ludwig + François + + + + +
+
+ + + +
+
+ 0 + 1.49 + 1.5 + 3 + 4 + 5 +
+
+ + + +
+
+ + +
+
+ +
+
+ +
+
+ +
+ +
+
+ +
+
+
+ ); + } + + export default App; diff --git a/src/components/BoxColor.css b/src/components/BoxColor.css new file mode 100644 index 0000000..3aa3494 --- /dev/null +++ b/src/components/BoxColor.css @@ -0,0 +1,20 @@ +.box-color { + width: 80%; /* Adjust width as needed */ + height: 150px; /* Adjust height as needed */ + display: flex; + align-items: center; + flex-direction: column; /* Stack text vertically */ + justify-content: center; + color: white; + font-family: Arial, sans-serif; + border: 2px solid black; /* Optional: border to define the box */ + margin-bottom: 20px; + margin-left: 10px; + } + + .box-color p { + margin: 0; + font-size: 30px; + /* Optional: adjust spacing between lines */ + line-height: 1.5; + } \ No newline at end of file diff --git a/src/components/BoxColor.js b/src/components/BoxColor.js new file mode 100644 index 0000000..b14b379 --- /dev/null +++ b/src/components/BoxColor.js @@ -0,0 +1,36 @@ +import React from 'react'; +import './BoxColor.css'; + +// Function to convert RGB to Hex +const rgbToHex = (r, g, b) => { + const toHex = (num) => { + const hex = num.toString(16); + return hex.length === 1 ? '0' + hex : hex; + }; + return `#${toHex(r)}${toHex(g)}${toHex(b)}`.toLowerCase(); + }; + +const BoxColor = ({ r, g, b }) => { + // Ensure the values are within the valid range + const clampedR = Math.max(0, Math.min(255, r)); + const clampedG = Math.max(0, Math.min(255, g)); + const clampedB = Math.max(0, Math.min(255, b)); + + // Create the RGB color string + const rgbColor = `rgb(${clampedR}, ${clampedG}, ${clampedB})`; + + // Create the Hex color string + const hexColor = rgbToHex(clampedR, clampedG, clampedB); + + // Determine text color based on the RGB value + const textColor = (clampedR === 128 && clampedG === 255 && clampedB === 0) ? 'black' : 'white'; + + return ( +
+

{rgbColor}

+

{hexColor}

+
+ ); +}; + +export default BoxColor; \ No newline at end of file diff --git a/src/components/Carousel.css b/src/components/Carousel.css new file mode 100644 index 0000000..6dd70ec --- /dev/null +++ b/src/components/Carousel.css @@ -0,0 +1,26 @@ +.carousel { + display: flex; + align-items: center; + justify-content: center; + position: relative; + } + + .carousel-image { + width: 300px; + height: 200px; + object-fit: cover; + margin: 0 10px; + } + + .carousel-button { + background-color: #007bff; + color: white; + border: none; + padding: 10px; + cursor: pointer; + } + + .carousel-button:hover { + background-color: #0056b3; + } + \ No newline at end of file diff --git a/src/components/Carousel.js b/src/components/Carousel.js new file mode 100644 index 0000000..bae1914 --- /dev/null +++ b/src/components/Carousel.js @@ -0,0 +1,23 @@ +import React, { useState } from 'react'; + +const Carousel = ({ images }) => { + const [currentIndex, setCurrentIndex] = useState(0); + + const goToPrevious = () => { + setCurrentIndex((prevIndex) => (prevIndex - 1 + images.length) % images.length); + }; + + const goToNext = () => { + setCurrentIndex((prevIndex) => (prevIndex + 1) % images.length); + }; + + return ( +
+ + carousel + +
+ ); +}; + +export default Carousel; \ No newline at end of file diff --git a/src/components/ClickablePicture.js b/src/components/ClickablePicture.js new file mode 100644 index 0000000..310eb38 --- /dev/null +++ b/src/components/ClickablePicture.js @@ -0,0 +1,20 @@ +import React, { useState } from 'react'; + +const ClickablePicture = ({ img, imgClicked }) => { + const [isClicked, setIsClicked] = useState(false); + + const handleClick = () => { + setIsClicked(!isClicked); + }; + + return ( + Clickable + ); +}; + +export default ClickablePicture; diff --git a/src/components/CreditCard.css b/src/components/CreditCard.css new file mode 100644 index 0000000..5467358 --- /dev/null +++ b/src/components/CreditCard.css @@ -0,0 +1,44 @@ +.credit-card { + width: 300px; + height: 130px; + border-radius: 10px; + padding: 20px; + display: flex; + flex-direction: column; + justify-content: space-between; + font-family: Arial, sans-serif; + margin: 20px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); +} + +.card-logo { + display: flex; + justify-content: flex-end; +} + +.card-logo img { + margin-top: -15px; + width: 50px; + height: auto; +} + +.card-number { + font-size: 30px; + letter-spacing: 2px; + margin-top: -28px; +} + +.card-info { + font-size: 14px; + text-align: left; +} + +.bank { + margin-left: 30px; +} + +.owner { + display: flex; + margin-top: 20px; /* Optional: Adjust the spacing above the owner text */ + font-size: 14px; +} \ No newline at end of file diff --git a/src/components/CreditCard.js b/src/components/CreditCard.js new file mode 100644 index 0000000..7042f09 --- /dev/null +++ b/src/components/CreditCard.js @@ -0,0 +1,47 @@ +import React from 'react'; +import './CreditCard.css'; + +const CreditCard = ({ + type, + number, + expirationMonth, + expirationYear, + bank, + owner, + bgColor, + color, +}) => { + // Format the credit card number to show only the last 4 digits + const lastFourDigits = number.slice(-4); + + // Format the expiration month to always be two digits (e.g., '03' for March) + const formattedMonth = expirationMonth.toString().padStart(2, '0'); + + // Determine the credit card type logo + const cardLogo = type === 'Visa' ? '/img/visa.png' : '/img/mastercard.png'; + + return ( +
+
+ {`${type} +
+
+

•••• •••• •••• {lastFourDigits}

+
+
+ + Expires {formattedMonth}/{expirationYear} + + + {bank} + + +
+ {owner} +
+
+
+ ); +}; + +export default CreditCard; diff --git a/src/components/Dice.js b/src/components/Dice.js new file mode 100644 index 0000000..1b5f604 --- /dev/null +++ b/src/components/Dice.js @@ -0,0 +1,28 @@ +import React, { useState } from 'react'; + +const Dice = () => { + // State to keep track of the current dice image + const [diceImage, setDiceImage] = useState('/img/dice3.png'); + + const rollDice = () => { + // Set the dice to the empty image + setDiceImage('/img/dice-empty.png'); + + // After 1 second, change the image to a random dice image + setTimeout(() => { + const randomDiceValue = Math.floor(Math.random() * 6) + 1; + setDiceImage(`/img/dice${randomDiceValue}.png`); + }, 1000); + }; + + return ( + dice + ); +}; + +export default Dice; diff --git a/src/components/DriverCard.css b/src/components/DriverCard.css new file mode 100644 index 0000000..9024aa1 --- /dev/null +++ b/src/components/DriverCard.css @@ -0,0 +1,40 @@ +.driver-card { + display: flex; + align-items: center; + justify-content: flex-start; /* Keeps items in their natural flow */ + background-color: #455eb5; + color: white; + border-radius: 10px; + padding: 20px; + width: 700px; + margin: 20px auto; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + padding-left: 400px; + } + + .driver-img { + width: 100px; + height: 100px; + border-radius: 50%; + object-fit: cover; + margin-right: 20px; + } + + .driver-info { + flex-grow: 1; + display: flex; + flex-direction: column; + justify-content: center; /* Vertically centers the text within the info section */ + } + + .driver-info h2 { + margin: 0; + font-size: 24px; + text-align: left; + } + + .driver-info p { + margin: -5px 0 0; + font-size: 16px; + text-align: left; + } \ No newline at end of file diff --git a/src/components/DriverCard.js b/src/components/DriverCard.js new file mode 100644 index 0000000..63e0e6c --- /dev/null +++ b/src/components/DriverCard.js @@ -0,0 +1,18 @@ +import React from 'react'; +import './DriverCard.css'; +import Rating from './Rating'; + +const DriverCard = ({ name, rating, img, car }) => { + return ( +
+ {name} +
+

{name}

+ {rating} {/* Pass the prop to indicate it's within DriverCard */} +

{car.model} - {car.licensePlate}

+
+
+ ); +}; + +export default DriverCard; \ No newline at end of file diff --git a/src/components/Greetings.css b/src/components/Greetings.css new file mode 100644 index 0000000..1201755 --- /dev/null +++ b/src/components/Greetings.css @@ -0,0 +1,7 @@ +.greetings { + font-size: 35px; + text-align: left; + border: 2px solid black; + margin: 10px 10px; + padding: 6px 4px; +} \ No newline at end of file diff --git a/src/components/Greetings.js b/src/components/Greetings.js new file mode 100644 index 0000000..4ff426a --- /dev/null +++ b/src/components/Greetings.js @@ -0,0 +1,25 @@ +import React from 'react'; +import './Greetings.css'; + +function Greetings(props) { + const { lang, children } = props; + + // Map language codes to greetings + const greetings = { + de: 'Hallo', + en: 'Hello', + es: 'Hola', + fr: 'Bonjour', + }; + + // Get the appropriate greeting based on the lang prop + const greetingText = greetings[lang] || 'Hello'; // Default to 'Hello' if lang is not recognized + + return ( +
+ {greetingText} {children} +
+ ); +} + +export default Greetings; \ No newline at end of file diff --git a/src/components/IdCard.css b/src/components/IdCard.css new file mode 100644 index 0000000..baa07bc --- /dev/null +++ b/src/components/IdCard.css @@ -0,0 +1,24 @@ +.id-card { + display: flex; + align-items: center; + border: 2px solid black; + padding: 3px 7px; + margin: 10px 10px; +} + +.id-card img { + margin-right: 20px; + padding-top: 5px; + padding-bottom: 5px; +} + +.id-card-details { + margin-top: -30px; /* Apply the negative margin to the container */ +} + +.id-card-details p { + margin-left: -15px; + text-align: left; + line-height: 5px; + font-weight:500 +} \ No newline at end of file diff --git a/src/components/IdCard.js b/src/components/IdCard.js new file mode 100644 index 0000000..bc88353 --- /dev/null +++ b/src/components/IdCard.js @@ -0,0 +1,24 @@ +import React from 'react'; +import './IdCard.css'; + +function IdCard(props) { + const { lastName, firstName, gender, height, birth, picture } = props; + + // Format the birth date without timezone restrictions and remove commas + let formattedBirthDate = birth.toDateString().replace(/,/g, ''); // Format and remove commas + + return ( +
+ {`${firstName} +
+

First name: {firstName}

+

Last name: {lastName}

+

Gender: {gender}

+

Height: {(height / 100).toFixed(2)} m

+

Birth: {formattedBirthDate}

+
+
+ ); +} + +export default IdCard; \ No newline at end of file diff --git a/src/components/LikeButton.css b/src/components/LikeButton.css new file mode 100644 index 0000000..b211b54 --- /dev/null +++ b/src/components/LikeButton.css @@ -0,0 +1,13 @@ +.like-button { + padding: 10px 20px; + margin-right: 10px; + font-size: 18px; + color: white; + border: none; + cursor: pointer; + transition: background-color 0.3s ease; + } + + .like-button:hover { + opacity: 0.8; + } \ No newline at end of file diff --git a/src/components/LikeButton.js b/src/components/LikeButton.js new file mode 100644 index 0000000..89406b6 --- /dev/null +++ b/src/components/LikeButton.js @@ -0,0 +1,26 @@ +import React, { useState } from 'react'; +import './LikeButton.css'; + +const LikeButton = () => { + const [likes, setLikes] = useState(0); + const [colorIndex, setColorIndex] = useState(0); + + const colors = ['purple', 'blue', 'green', 'yellow', 'orange', 'red']; + + const handleClick = () => { + setLikes(likes + 1); + setColorIndex((colorIndex + 1) % colors.length); + }; + + return ( + + ); +}; + +export default LikeButton; \ No newline at end of file diff --git a/src/components/NumbersTable.css b/src/components/NumbersTable.css new file mode 100644 index 0000000..bd1c98d --- /dev/null +++ b/src/components/NumbersTable.css @@ -0,0 +1,25 @@ +.numbers-table { + display: grid; + grid-template-columns: repeat(5, 52px); /* 5 columns */ + grid-template-rows: repeat(3, 52px); /* 3 rows */ + gap: 0px; /* Space between numbers */ +} + +.number { + width: 50px; + height: 50px; + display: flex; + align-items: center; + justify-content: center; + border: 2px solid black; + font-size: 18px; + font-weight: 500; +} + +.even { + background-color: red; +} + +.odd { + color: black; +} \ No newline at end of file diff --git a/src/components/NumbersTable.js b/src/components/NumbersTable.js new file mode 100644 index 0000000..e3c9bb7 --- /dev/null +++ b/src/components/NumbersTable.js @@ -0,0 +1,21 @@ +import React from 'react'; +import './NumbersTable.css'; // Make sure to create and import this CSS file + +const NumbersTable = ({ limit }) => { + const numbers = Array.from({ length: limit }, (_, i) => i + 1); + + return ( +
+ {numbers.map((number) => ( +
+ {number} +
+ ))} +
+ ); +}; + +export default NumbersTable; \ No newline at end of file diff --git a/src/components/RGBColorPicker.js b/src/components/RGBColorPicker.js new file mode 100644 index 0000000..d47351d --- /dev/null +++ b/src/components/RGBColorPicker.js @@ -0,0 +1,73 @@ +import React, { useState } from 'react'; +import SingleColorPicker from './SingleColorPicker'; + +const RGBColorPicker = () => { + const [rValue, setRValue] = useState(0); + const [gValue, setGValue] = useState(0); + const [bValue, setBValue] = useState(0); + + return ( +
+
+ setRValue(Number(value))} + /> + setGValue(Number(value))} + /> + setBValue(Number(value))} + /> +
+ +
+
+
+ rgb({rValue},{gValue},{bValue}) +
+
+
+ ); +}; + +const styles = { + container: { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + paddingTop: '100px', + }, + pickersContainer: { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + marginBottom: '20px', + }, + colorAndText: { + display: 'flex', + alignItems: 'center', + }, +}; + +export default RGBColorPicker; \ No newline at end of file diff --git a/src/components/Random.css b/src/components/Random.css new file mode 100644 index 0000000..a16655a --- /dev/null +++ b/src/components/Random.css @@ -0,0 +1,8 @@ +.random +{ + font-size: 35px; + text-align: left; + border: 2px solid black; + margin: 10px 10px; + padding: 6px 4px; +} diff --git a/src/components/Random.js b/src/components/Random.js new file mode 100644 index 0000000..9a1f537 --- /dev/null +++ b/src/components/Random.js @@ -0,0 +1,18 @@ +import React from 'react'; +import './Rating.css'; + +const Rating = ({ children, isDriverCard }) => { + const roundedRating = Math.round(children); + const stars = '★'.repeat(roundedRating) + '☆'.repeat(5 - roundedRating); + + const textColor = isDriverCard ? 'white' : 'black'; // Conditionally set the text color + const textAlign = isDriverCard ? 'left' : 'center'; // Conditionally set the text-align + + return ( +
+ {stars} +
+ ); +}; + +export default Rating; \ No newline at end of file diff --git a/src/components/Rating.css b/src/components/Rating.css new file mode 100644 index 0000000..45bbe5f --- /dev/null +++ b/src/components/Rating.css @@ -0,0 +1,5 @@ +.rating { + font-size: 24px; /* Adjust the size of the stars */ + color: black; /* Color for the filled stars */ + } + diff --git a/src/components/Rating.js b/src/components/Rating.js new file mode 100644 index 0000000..b590053 --- /dev/null +++ b/src/components/Rating.js @@ -0,0 +1,18 @@ +import React from 'react'; +import './Rating.css'; + +const Rating = ({ children, isDriverCard }) => { + const roundedRating = Math.round(children); + const stars = '★'.repeat(roundedRating) + '☆'.repeat(5 - roundedRating); + + const textColor = isDriverCard ? 'white' : 'black'; // Conditionally set the text color + const textAlign = isDriverCard ? 'left' : 'center'; // Conditionally set the text-align + + return ( +
+ {stars} +
+ ); +}; + +export default Rating; \ No newline at end of file diff --git a/src/components/SingleColorPicker.js b/src/components/SingleColorPicker.js new file mode 100644 index 0000000..5554bb8 --- /dev/null +++ b/src/components/SingleColorPicker.js @@ -0,0 +1,46 @@ +import React from 'react'; + +const SingleColorPicker = ({ color, value, onChange }) => { + const handleInputChange = (e) => { + onChange(e.target.value); + }; + + const getColorLabel = (color) => { + switch (color) { + case 'r': + return 'R:'; + case 'g': + return 'G:'; + case 'b': + return 'B:'; + default: + return ''; + } + }; + + return ( +
+
+ + +
+ ); +}; + +export default SingleColorPicker;