diff --git a/src/App.css b/src/App.css
index 74b5e05..7069533 100644
--- a/src/App.css
+++ b/src/App.css
@@ -7,6 +7,15 @@
pointer-events: none;
}
+.card-container {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 20px;
+ justify-content: center;
+ padding: 20px;
+}
+
+
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
diff --git a/src/App.js b/src/App.js
index 3784575..e5e3777 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,23 +1,104 @@
-import logo from './logo.svg';
-import './App.css';
+import IdCard from "./components/IdCard";
+import Greetings from "./components/Greetings";
+import Random from "./components/Randoms";
+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 picture from '../src/assets/images/maxence.png'
+import picture2 from '../src/assets/images/maxence-glasses.png'
+import "./App.css";
function App() {
return (
-
+
+
+
Ludwig
+
François
+
John
+
Carlos
+
+
+
+
+
+
+
+
+
+
0
+
1.49
+
1.5
+
3
+
4
+
5
+
+
+
+
);
}
diff --git a/src/components/BoxColor.js b/src/components/BoxColor.js
new file mode 100644
index 0000000..2f6a635
--- /dev/null
+++ b/src/components/BoxColor.js
@@ -0,0 +1,22 @@
+export default function BoxColor(props) {
+ const { r, g, b } = props;
+ const isValidColor = (value) => value >= 0 && value <= 255;
+ const validatedR = isValidColor(r) ? r : 0;
+ const validatedG = isValidColor(g) ? g : 0;
+ const validatedB = isValidColor(b) ? b : 0;
+
+ const style = {
+ backgroundColor: `rgb(${validatedR}, ${validatedG}, ${validatedB})`,
+ color: (validatedR + validatedG + validatedB) > 382 ? 'black' : 'white',
+ padding: '20px',
+ borderRadius: '8px',
+ textAlign: 'center',
+ marginBottom: '10px',
+ };
+
+ return (
+
+ rgb({validatedR}, {validatedG}, {validatedB})
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/ClickablePicture.js b/src/components/ClickablePicture.js
new file mode 100644
index 0000000..695a61f
--- /dev/null
+++ b/src/components/ClickablePicture.js
@@ -0,0 +1,17 @@
+import { useState } from 'react';
+export default function ClickablePicture({ img, imgClicked }) {
+ const [isClicked, setIsClicked] = useState(false);
+
+ const handleClick = () => {
+ setIsClicked(!isClicked);
+ };
+
+ return (
+
+ );
+}
diff --git a/src/components/CreditCard.js b/src/components/CreditCard.js
new file mode 100644
index 0000000..1a770f0
--- /dev/null
+++ b/src/components/CreditCard.js
@@ -0,0 +1,66 @@
+export default function CreditCard(props) {
+ const {
+ type,
+ number,
+ expirationMonth,
+ expirationYear,
+ bank,
+ owner,
+ bgColor,
+ color
+ } = props;
+
+ const lastFourDigits = number.slice(-4);
+
+ const formattedMonth = expirationMonth.toString().padStart(2, '0');
+ const formattedYear = expirationYear.toString().slice(-2);
+
+ const cardStyle = {
+ backgroundColor: bgColor,
+ color: color,
+ width: '300px',
+ height: '180px',
+ borderRadius: '10px',
+ padding: '20px',
+ display: 'flex',
+ flexDirection: 'column',
+ justifyContent: 'space-between',
+ fontFamily: 'Arial, sans-serif',
+ color: color,
+ position: 'relative'
+ };
+
+ const logoStyle = {
+ position: 'absolute',
+ top: '10px',
+ right: '10px',
+ fontSize: '24px'
+ };
+
+ const cardNumberStyle = {
+ fontSize: '24px',
+ letterSpacing: '2px'
+ };
+
+ const infoStyle = {
+ display: 'flex',
+ justifyContent: 'space-between',
+ fontSize: '14px'
+ };
+
+ return (
+
+
+ {type === 'Visa' ? 'V' : 'M'}
+
+
+ **** **** **** {lastFourDigits}
+
+
+
{bank}
+
{formattedMonth}/{formattedYear}
+
+
{owner}
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/DriverCard.js b/src/components/DriverCard.js
new file mode 100644
index 0000000..4d49057
--- /dev/null
+++ b/src/components/DriverCard.js
@@ -0,0 +1,59 @@
+export default function DriverCard({ name, rating, img, car }) {
+ // Ensure rating is between 0 and 5
+ const validatedRating = Math.max(0, Math.min(5, parseFloat(rating)));
+
+ // Format the rating to one decimal place
+ const formattedRating = validatedRating.toFixed(1);
+
+ // Card styles
+ const cardStyle = {
+ display: "flex",
+ alignItems: "center",
+ backgroundColor: "#f8f9fa",
+ borderRadius: "10px",
+ padding: "20px",
+ boxShadow: "0 4px 8px rgba(0, 0, 0, 0.1)",
+ width: "400px",
+ margin: "20px 0",
+ };
+
+ const imgStyle = {
+ borderRadius: "50%",
+ width: "80px",
+ height: "80px",
+ marginRight: "20px",
+ };
+
+ const textStyle = {
+ display: "flex",
+ flexDirection: "column",
+ justifyContent: "center",
+ };
+
+ const nameStyle = {
+ fontSize: "18px",
+ fontWeight: "bold",
+ };
+
+ const ratingStyle = {
+ color: "#f39c12",
+ };
+
+ const carStyle = {
+ fontSize: "14px",
+ color: "#333",
+ };
+
+ return (
+
+

+
+
{name}
+
{formattedRating} ★
+
+ {car.model} - {car.licensePlate}
+
+
+
+ );
+}
diff --git a/src/components/Greetings.js b/src/components/Greetings.js
new file mode 100644
index 0000000..2ee0a81
--- /dev/null
+++ b/src/components/Greetings.js
@@ -0,0 +1,16 @@
+const greetings = {
+ de: 'Hallo',
+ en: 'Hello',
+ es: 'Hola',
+ fr: 'Bonjour'
+};
+export default function Greetings(props) {
+ const { lang, children } = props;
+ const greeting = greetings[lang] || 'Hello';
+
+ return (
+
+ {greeting}, {children}!
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/IdCard.css b/src/components/IdCard.css
new file mode 100644
index 0000000..cd0d6b3
--- /dev/null
+++ b/src/components/IdCard.css
@@ -0,0 +1,20 @@
+.id-card {
+ display: flex;
+ align-items: center;
+ border: 1px solid #ccc;
+ border-radius: 8px;
+ padding: 16px;
+ margin-bottom: 16px;
+ background-color: #f9f9f9;
+}
+
+.id-card-picture {
+ border-radius: 50%;
+ width: 100px;
+ height: 100px;
+ margin-right: 16px;
+}
+
+.id-card-info p {
+ margin: 4px 0;
+}
diff --git a/src/components/IdCard.js b/src/components/IdCard.js
new file mode 100644
index 0000000..2c5abe1
--- /dev/null
+++ b/src/components/IdCard.js
@@ -0,0 +1,30 @@
+import './IdCard.css';
+export default function IdCard(props) {
+ const { lastName, firstName, gender, height, birth, picture } = props;
+ return (
+
+

+
+
+ First Name: {firstName}
+
+
+ Last Name: {lastName}
+
+
+ Gender: {gender}
+
+
+ Height: {height} cm
+
+
+ Birth: {birth.toDateString()}
+
+
+
+ );
+}
diff --git a/src/components/LikeButton.js b/src/components/LikeButton.js
new file mode 100644
index 0000000..c79e81f
--- /dev/null
+++ b/src/components/LikeButton.js
@@ -0,0 +1,29 @@
+import { useState } from "react";
+
+const colors = ["purple", "blue", "green", "yellow", "orange", "red"];
+export default function LikeButton() {
+ const [likes, setLikes] = useState(0);
+ const [colorIndex, setColorIndex] = useState(0);
+
+ const handleClick = () => {
+ setLikes(likes + 1);
+ setColorIndex((colorIndex + 1) % colors.length);
+ };
+
+ return (
+
+ );
+}
diff --git a/src/components/Randoms.js b/src/components/Randoms.js
new file mode 100644
index 0000000..4277f48
--- /dev/null
+++ b/src/components/Randoms.js
@@ -0,0 +1,11 @@
+export default function Random(props) {
+ const { min, max } = props;
+
+ const randomNumber = Math.floor(Math.random() * (max - min + 1)) + min;
+
+ return (
+
+ Random value between {min} and {max} is {randomNumber}
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/Rating.js b/src/components/Rating.js
new file mode 100644
index 0000000..0ea6942
--- /dev/null
+++ b/src/components/Rating.js
@@ -0,0 +1,15 @@
+export default function Rating({ children }) {
+ const value = Math.max(0, Math.min(5, parseFloat(children)));
+
+ const roundedValue = Math.round(value);
+
+ const stars = Array.from({ length: 5 }, (_, index) =>
+ index < roundedValue ? '★' : '☆'
+ );
+
+ return (
+
+ {stars.join(' ')}
+
+ );
+}
\ No newline at end of file