diff --git a/package-lock.json b/package-lock.json index 46ab017a..ae5972ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,9 @@ "dotenv": "^16.4.5", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-icons": "^5.2.1", "react-redux": "^9.1.2", + "react-responsive-carousel": "^3.2.23", "react-router-dom": "^6.23.1", "redux": "^5.0.1" }, @@ -2701,6 +2703,11 @@ "node": ">= 6" } }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" + }, "node_modules/cli-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", @@ -5971,7 +5978,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -6564,7 +6570,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -6574,8 +6579,7 @@ "node_modules/prop-types/node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/proxy-from-env": { "version": "1.1.0", @@ -6646,6 +6650,25 @@ "react": "^18.3.1" } }, + "node_modules/react-easy-swipe": { + "version": "0.0.21", + "resolved": "https://registry.npmjs.org/react-easy-swipe/-/react-easy-swipe-0.0.21.tgz", + "integrity": "sha512-OeR2jAxdoqUMHIn/nS9fgreI5hSpgGoL5ezdal4+oO7YSSgJR8ga+PkYGJrSrJ9MKlPcQjMQXnketrD7WNmNsg==", + "dependencies": { + "prop-types": "^15.5.8" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/react-icons": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.2.1.tgz", + "integrity": "sha512-zdbW5GstTzXaVKvGSyTaBalt7HSfuK5ovrzlpyiWHAFXndXTdd/1hdDHI4xBM1Mn7YriT6aqESucFl9kEXzrdw==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -6684,6 +6707,16 @@ "node": ">=0.10.0" } }, + "node_modules/react-responsive-carousel": { + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/react-responsive-carousel/-/react-responsive-carousel-3.2.23.tgz", + "integrity": "sha512-pqJLsBaKHWJhw/ItODgbVoziR2z4lpcJg+YwmRlSk4rKH32VE633mAtZZ9kDXjy4wFO+pgUZmDKPsPe1fPmHCg==", + "dependencies": { + "classnames": "^2.2.5", + "prop-types": "^15.5.8", + "react-easy-swipe": "^0.0.21" + } + }, "node_modules/react-router": { "version": "6.23.1", "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.1.tgz", diff --git a/package.json b/package.json index 277b0e7d..717fd8c6 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,9 @@ "dotenv": "^16.4.5", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-icons": "^5.2.1", "react-redux": "^9.1.2", + "react-responsive-carousel": "^3.2.23", "react-router-dom": "^6.23.1", "redux": "^5.0.1" }, diff --git a/src/App.tsx b/src/App.tsx index 4be4e8eb..805ee355 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,6 @@ +import AppRoutes from '@/routes/AppRoutes'; + function App() { - return

Welcome to Dynamites E-commerce

; + return ; } - export default App; diff --git a/src/assets/welcome.jpg b/src/assets/welcome.jpg new file mode 100644 index 00000000..ffc50c9c Binary files /dev/null and b/src/assets/welcome.jpg differ diff --git a/src/components/FrontFooter.tsx b/src/components/FrontFooter.tsx new file mode 100644 index 00000000..c982d63a --- /dev/null +++ b/src/components/FrontFooter.tsx @@ -0,0 +1,5 @@ +function FrontFooter() { + return
Front Footer
; +} + +export default FrontFooter; diff --git a/src/components/NavBar.tsx b/src/components/NavBar.tsx new file mode 100644 index 00000000..4aeab5d3 --- /dev/null +++ b/src/components/NavBar.tsx @@ -0,0 +1,4 @@ +function NavBar() { + return
Nav Bar
; +} +export default NavBar; diff --git a/src/components/Slider.tsx b/src/components/Slider.tsx new file mode 100644 index 00000000..b6a86628 --- /dev/null +++ b/src/components/Slider.tsx @@ -0,0 +1,56 @@ +import React, { useState } from 'react'; + +interface SlideProps { + image: string; + title: string; + description: string; + price: string; +} + +const slides: SlideProps[] = [ + { image: '/path_to_image1.jpg', title: 'Product 1', description: 'Description 1', price: '$330' }, + { image: '/path_to_image2.jpg', title: 'Product 2', description: 'Description 2', price: '$123' }, +]; + +const Slider: React.FC = () => { + const [currentSlide, setCurrentSlide] = useState(0); + + const nextSlide = () => { + setCurrentSlide((prevSlide) => (prevSlide + 1) % slides.length); + }; + + const prevSlide = () => { + setCurrentSlide((prevSlide) => (prevSlide === 0 ? slides.length - 1 : prevSlide - 1)); + }; + + return ( +
+ +
+ {slides.map((slide, index) => ( +
+ {slide.title} +
+

{slide.title}

+

{slide.description}

+ {slide.price} +
+
+ ))} +
+ +
+ ); +}; + +export default Slider; diff --git a/src/components/form/HSButton.tsx b/src/components/form/HSButton.tsx new file mode 100644 index 00000000..b44f0f59 --- /dev/null +++ b/src/components/form/HSButton.tsx @@ -0,0 +1,37 @@ +import { Link } from 'react-router-dom'; + +interface MyButtonProps { + path?: string; + title: string; + styles?: string; + click?: () => void; + icon?: JSX.Element; + target?: '_blank' | '_self' | '_parent' | '_top'; + onChange?: React.ChangeEventHandler; +} + +function HSButton({ + path, + click, + title, + icon, + styles, + target, + onChange, +}: MyButtonProps) { + return ( + + {title} {icon} + + ); +} + +export default HSButton; diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx new file mode 100644 index 00000000..64f2423f --- /dev/null +++ b/src/pages/Home.tsx @@ -0,0 +1,121 @@ +import React, { useState } from 'react'; +import Navbar from '@/components/NavBar'; +import Footer from '@/components/FrontFooter'; +import HSButton from '@/components/form/HSButton'; +import HelloImage from '@/assets/welcome.jpg'; +import { SlArrowLeft } from "react-icons/sl"; +import { SlArrowRight } from "react-icons/sl";interface SlideProps { + title: string; + mainText: string[]; + buttonText: string; + img: string; +} + +const slides: SlideProps[] = [ + { + title: 'Absolutely hot collections🔥', + mainText: ['The Best Place To', 'Find And Buyer', 'Amazing Product'], + buttonText: 'Shop now!', + img: HelloImage, + }, + { + title: 'Absolutely hot collections🔥', + mainText: ['The Best Place To', 'Find And Buyer', 'Amazing Product'], + buttonText: 'Shop now!', + img: HelloImage, + }, + { + title: 'Absolutely hot collections🔥', + mainText: ['The Best Place To', 'Find And Buyer', 'Amazing Product'], + buttonText: 'Shop now!', + img: HelloImage, + }, +]; + +const Slide: React.FC<{ slide: SlideProps }> = ({ slide }) => ( +
+
+

{slide.title}

+
+ {slide.mainText.map((text, index) => ( +

+ {index === 2 ? ( + <> + {text.split(' ')[0]} + {text.split(' ')[1]} + + ) : ( + text + )} +

+ ))} +
+ +
+
+ Slide Image +
+
+); + +const Slider: React.FC = () => { + const [currentIndex, setCurrentIndex] = useState(0); + + const handlePrev = () => { + setCurrentIndex((prevIndex) => (prevIndex === 0 ? slides.length - 1 : prevIndex - 1)); + }; + + const handleNext = () => { + setCurrentIndex((prevIndex) => (prevIndex === slides.length - 1 ? 0 : prevIndex + 1)); + }; + + return ( +
+
+ {slides.map((slide, index) => ( +
+ +
+ ))} +
+ + +
+ ); +}; + +function Home() { + return ( +
+
+ +
+
+
+ +
+
+
+
+ ); +} + +export default Home; \ No newline at end of file diff --git a/src/pages/home b/src/pages/home deleted file mode 100644 index e69de29b..00000000 diff --git a/src/components/button b/src/redux/store.tsx similarity index 100% rename from src/components/button rename to src/redux/store.tsx diff --git a/src/routes/AppRoutes.tsx b/src/routes/AppRoutes.tsx new file mode 100644 index 00000000..59f11507 --- /dev/null +++ b/src/routes/AppRoutes.tsx @@ -0,0 +1,14 @@ +import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; +import Home from '@/pages/Home'; + +function AppRoutes() { + return ( + + + } /> + + + ); +} + +export default AppRoutes; diff --git a/tailwind.config.js b/tailwind.config.js index 8c0ec37c..1b46e62b 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -2,7 +2,26 @@ export default { content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'], theme: { - extend: {}, + screens: { + xs: '320px', + sm: '360px', + md: '768px', + lg: '1024px', + xl: '1280px', + '2xl': '1536px', + '3xl': '1920px', + '4xl': '2560px', + samsung: '412px', + iphone: '414px', + tablet: '640px', + desktop: '1280px', + landscape: { raw: '(min-height: 360px) and (orientation: landscape)' }, + }, + extend: { + fontFamily: { + secondary: ['Anton', 'sans-serif'], + }, + }, }, plugins: [], -}; \ No newline at end of file +};