diff --git a/apps/web/src/App.css b/apps/web/src/App.css index b9d355d..82e2935 100644 --- a/apps/web/src/App.css +++ b/apps/web/src/App.css @@ -1,42 +1,5 @@ #root { - max-width: 1280px; + /* max-width: 1280px; */ margin: 0 auto; - padding: 2rem; text-align: center; } - -.logo { - height: 6em; - padding: 1.5em; - will-change: filter; - transition: filter 300ms; -} -.logo:hover { - filter: drop-shadow(0 0 2em #646cffaa); -} -.logo.react:hover { - filter: drop-shadow(0 0 2em #61dafbaa); -} - -@keyframes logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} - -@media (prefers-reduced-motion: no-preference) { - a:nth-of-type(2) .logo { - animation: logo-spin infinite 20s linear; - } -} - -.card { - padding: 2em; -} - -.read-the-docs { - color: #888; -} diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx index 7d4aa37..bb4294d 100644 --- a/apps/web/src/App.tsx +++ b/apps/web/src/App.tsx @@ -1,143 +1,29 @@ -import { useState } from "react"; -import reactLogo from "./assets/react.svg"; -import viteLogo from "/vite.svg"; +import { BaseWrapper } from "./components/BaseComponents/BaseWrapper"; import "./App.css"; -import { FaSignInAlt } from "react-icons/fa"; -import { Button } from "./components"; +// import reactLogo from './assets/react.svg'; +// import viteLogo from '/vite.svg'; +// import { FaSignInAlt } from 'react-icons/fa'; +// import { Button } from './components'; function App() { - const [count, setCount] = useState(0); - return ( - <> -
- - Vite logo - - - React logo - -
-

Vite + React

-
- -

- Edit src/App.tsx and save to test HMR -

-
-

- Click on the Vite and React logos to learn more -

-
-
- + + Hello! + ); } diff --git a/apps/web/src/components/BaseComponents/BaseWrapper.css b/apps/web/src/components/BaseComponents/BaseWrapper.css new file mode 100644 index 0000000..55bc480 --- /dev/null +++ b/apps/web/src/components/BaseComponents/BaseWrapper.css @@ -0,0 +1,20 @@ +.base-wrapper { + display: flex; + flex-direction: column; + min-height: 100vh; + width: 100vw; +} + +.base-wrapper__content { + flex: 1; + padding: 16px; + background-color: #f5f5f5; +} + +.base-wrapper__footer { + padding: 16px; + background-color: #1976d2; + color: white; + text-align: center; + font-size: 14px; +} diff --git a/apps/web/src/components/BaseComponents/BaseWrapper.tsx b/apps/web/src/components/BaseComponents/BaseWrapper.tsx new file mode 100644 index 0000000..70c32ce --- /dev/null +++ b/apps/web/src/components/BaseComponents/BaseWrapper.tsx @@ -0,0 +1,23 @@ +import React from "react"; +import { Header, HeaderProps } from "../Header/Header"; +import { Footer } from "../Footer/Footer"; +import "./BaseWrapper.css"; + +export interface BaseWrapperProps { + /** Header configuration */ + headerProps: HeaderProps; + /** Main content of the page */ + children: React.ReactNode; +} + +const BaseWrapper: React.FC = ({ headerProps, children }) => { + return ( +
+
+
{children}
+
+
+ ); +}; + +export { BaseWrapper }; diff --git a/apps/web/src/components/Footer/Footer.css b/apps/web/src/components/Footer/Footer.css index 9fdceda..40cb438 100644 --- a/apps/web/src/components/Footer/Footer.css +++ b/apps/web/src/components/Footer/Footer.css @@ -1 +1,163 @@ -/* Base Styles */ +.footer { + width: 100%; + max-width: 1280px; + /* */ + background-color: #1e1e1e; + color: #fff; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.35); + border-radius: 16px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 56px; + gap: 16px; + /* */ + margin: 0 auto; + margin-bottom: 32px; +} + +.footer__top { + display: flex; + justify-content: space-between; + width: 100%; +} + +.footer__info { + width: 100%; + border: 1px solid #868686; + border-radius: 16px; + padding: 16px; + display: flex; + flex-direction: row; + justify-content: space-around; + align-items: center; + gap: 32px; +} + +.footer__info-item { + display: flex; + flex-direction: row-reverse; + align-items: center; + text-align: center; +} + +.footer__info-content { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; +} + +.footer__info-title { + font-size: 16px; + font-weight: bold; +} + +.footer__info-text { + font-size: 14px; +} + +.footer__info-icon { + font-size: 32px; + width: 40px; + height: 40px; + border: 1px solid #868686aa; + border-radius: 16px; + padding: 8px; + margin-left: 8px; +} + +.footer__middle { + display: flex; + flex-direction: row; + justify-content: space-between; + padding: 24px 64px; +} + +.footer__about { + flex: 1; + font-size: 14px; + line-height: 1.5; +} + +.footer__logo { + font-size: 20px; + font-weight: bold; + display: flex; + justify-content: start; + align-items: center; + justify-items: start; +} + +.footer__logo_svg { + width: 92px; + height: 92px; +} + +.footer__links { + flex: 1; +} + +.footer__link-title { + font-size: 16px; + font-weight: bold; +} + +.footer__links ul { + list-style: none; + padding: 0; + margin: 8px 0 0 0; +} + +.footer__links li { + font-size: 14px; + margin-top: 8px; +} + +.footer__newsletter { + flex: 1; + display: flex; + flex-direction: column; +} + +.footer__newsletter-title { + font-size: 16px; + font-weight: bold; + margin-bottom: 8px; +} + +.footer__newsletter-form { + display: flex; + gap: 8px; +} + +.footer__newsletter-form input { + flex: 1; + padding: 8px; + font-size: 14px; + border: none; + border-radius: 4px; +} + +.footer__newsletter-form button { + padding: 8px 16px; + background-color: #fdb713; + border: none; + border-radius: 4px; + font-size: 14px; + color: #1e1e1e; + cursor: pointer; +} + +.footer__newsletter-form button:hover { + background-color: #e0a602; +} + +.footer__bottom { + width: 100%; + text-align: center; + padding-top: 16px; + border-top: 1px solid rgba(255, 255, 255, 0.2); + font-size: 12px; +} diff --git a/apps/web/src/components/Footer/Footer.tsx b/apps/web/src/components/Footer/Footer.tsx index 71fe202..e79834b 100644 --- a/apps/web/src/components/Footer/Footer.tsx +++ b/apps/web/src/components/Footer/Footer.tsx @@ -1,11 +1,82 @@ import React from "react"; import "./Footer.css"; +import { Logo } from "../Logo/Logo"; -export interface FooterProps extends React.HTMLAttributes {} +const Footer: React.FC = () => { + const [newsletterEmail, setNewsletterEmail] = React.useState(""); -const Footer = ({ ...props }: FooterProps) => { - const classNames = []; - return
; + const handleSubscribe = () => { + if (newsletterEmail.trim()) { + alert(`Subscribed with: ${newsletterEmail}`); + setNewsletterEmail(""); + } + }; + + return ( +
+
+
+
+
+ ارتباط با ما + 0912-2123456 +
+ 📞 +
+
+
+ ایمیل + autorent@info.com +
+ 📧 +
+
+
+ آدرس + تهران - خ شادمان +
+ 📍 +
+
+
+
+
+
+ + رنت‌منت! +
+

+ رنت‌منت با رویکرد اعتماد به مشتری با در اختیار داشتن بزرگترین ناوگان + خودروئی شامل از انواع خودروهای سفر کوتاه، اقتصادی تا تجاری در سراسر + کشور ایران آماده خدمت‌رسانی به مشتریان است. +

+
+
+ دسترسی آسان +
    +
  • سوالات متداول
  • +
  • تماس با ما
  • +
  • درباره ما
  • +
+
+
+ خبرنامه +
+ setNewsletterEmail(e.target.value)} + /> + +
+
+
+
+

تمامی حقوق این وبسایت متعلق به رنت‌منت می‌باشد ©

+
+
+ ); }; export { Footer }; diff --git a/apps/web/src/components/Header/Header.stories.ts b/apps/web/src/components/Header/Header.stories.ts deleted file mode 100644 index 28e09fd..0000000 --- a/apps/web/src/components/Header/Header.stories.ts +++ /dev/null @@ -1,33 +0,0 @@ -import type { Meta, StoryObj } from "@storybook/react"; -import { fn } from "@storybook/test"; - -import { Header } from "./Header"; - -const meta: Meta = { - title: "Sections/Header", - component: Header, - // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs - tags: ["autodocs"], - parameters: { - // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout - layout: "fullscreen", - }, - args: { - onLogin: fn(), - onLogout: fn(), - onCreateAccount: fn(), - }, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const LoggedIn: Story = { - args: { - user: { - name: "Jane Doe", - }, - }, -}; - -export const LoggedOut: Story = {}; diff --git a/apps/web/src/components/Header/Header.stories.tsx b/apps/web/src/components/Header/Header.stories.tsx new file mode 100644 index 0000000..f94f131 --- /dev/null +++ b/apps/web/src/components/Header/Header.stories.tsx @@ -0,0 +1,46 @@ +import React from "react"; +import { Meta, StoryFn } from "@storybook/react"; +import { Header, HeaderProps } from "./Header"; + +const meta: Meta = { + title: "Components/Header", + component: Header, + argTypes: { + navLinks: { control: "object" }, + user: { control: "object" }, + onSearchClick: { action: "Search clicked" }, + onLogin: { action: "Login clicked" }, + onLogout: { action: "Logout clicked" }, + onCreateAccount: { action: "Create account clicked" }, + }, +}; + +export default meta; + +const Template: StoryFn = (args) =>
; + +export const LoggedIn = Template.bind({}); +LoggedIn.args = { + navLinks: [ + { label: "رزرو خودرو", href: "#" }, + { label: "خدمات ما", href: "#" }, + { label: "بلاگ", href: "#" }, + { label: "درباره ما", href: "#" }, + { label: "تماس با ما", href: "#" }, + ], + user: { + name: "اولدوز بهاور", + avatarUrl: "https://via.placeholder.com/32", + }, +}; + +export const LoggedOut = Template.bind({}); +LoggedOut.args = { + navLinks: [ + { label: "رزرو خودرو", href: "#" }, + { label: "خدمات ما", href: "#" }, + { label: "بلاگ", href: "#" }, + { label: "درباره ما", href: "#" }, + { label: "تماس با ما", href: "#" }, + ], +}; diff --git a/apps/web/src/components/Header/Header.tsx b/apps/web/src/components/Header/Header.tsx index 7253b9e..97774ce 100644 --- a/apps/web/src/components/Header/Header.tsx +++ b/apps/web/src/components/Header/Header.tsx @@ -1,68 +1,82 @@ import React from "react"; -import { Button } from "../Button/Button"; -import "./header.css"; - -type User = { - name: string; -}; +import { Logo } from "../Logo/Logo"; +import "./Header.css"; export interface HeaderProps { - user?: User; + /** Navigation links */ + navLinks: { label: string; href: string }[]; + /** Logged-in user data */ + user?: { + name: string; + avatarUrl: string; + }; + /** Search icon or search functionality */ + onSearchClick?: () => void; + /** Callback when login button is clicked */ onLogin?: () => void; + /** Callback when logout button is clicked */ onLogout?: () => void; + /** Callback when create account button is clicked */ onCreateAccount?: () => void; } -const Header = ({ user, onLogin, onLogout, onCreateAccount }: HeaderProps) => ( -
-
-
- - - - - - - -

Acme

+const Header: React.FC = ({ + navLinks, + user, + onSearchClick, + onLogin, + onLogout, + onCreateAccount, +}) => { + return ( +
+
+ + رنت‌منت!
-
+ +
{user ? ( - <> - - Welcome, {user.name}! - - */} +
) : ( - <> - + +
)}
-
-
-); +
+ ); +}; export { Header }; diff --git a/apps/web/src/components/Header/header.css b/apps/web/src/components/Header/header.css index eb0a337..b7200b7 100644 --- a/apps/web/src/components/Header/header.css +++ b/apps/web/src/components/Header/header.css @@ -1,31 +1,124 @@ -.storybook-header { +.header { + /* */ + height: 4rem; + width: 100%; + max-width: 1280px; + margin: 0 auto; + margin-bottom: 1rem; + border-radius: 0px 0px 16px 16px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + /* */ display: flex; justify-content: space-between; align-items: center; - border-bottom: 1px solid rgba(0, 0, 0, 0.1); - padding: 15px 20px; + background-color: #fff; + padding: 16px 32px; } -.storybook-header svg { - display: inline-block; - vertical-align: top; +.header__logo { + font-size: 20px; + font-weight: bold; + display: flex; + justify-content: end; + align-items: center; + justify-items: end; } -.storybook-header h1 { - display: inline-block; - vertical-align: top; - margin: 6px 0 6px 10px; - font-weight: 700; - font-size: 20px; - line-height: 1; +.header__logo_svg { + width: 92px; + height: 92px; + display: flex; + flex-direction: row; +} + +.header__nav { + display: flex; + gap: 32px; +} + +.header__link { + text-decoration: none; + color: #333; + font-size: 16px; + font-weight: 500; + transition: color 0.2s; + display: inline-flex; + align-items: center; } -.storybook-header button + button { - margin-left: 10px; +.header__link:hover { + color: #1976d2; +} + +.header__actions { + display: flex; + align-items: center; + gap: 16px; } -.storybook-header .welcome { - margin-right: 10px; +.header__search { + background: none; + border: none; + font-size: 18px; + cursor: pointer; color: #333; +} + +.header__search:hover { + color: #1976d2; +} + +.header__user { + display: flex; + align-items: center; + gap: 8px; +} + +.header__avatar { + width: 40px; + height: 40px; + border-radius: 50%; +} + +.header__username { + font-size: 16px; + color: #333; +} + +/* Add styles for the new buttons */ +.header__auth-buttons { + display: flex; + gap: 8px; +} + +.header__login, +.header__create-account { + background-color: #1976d2; + color: #fff; + border: none; + border-radius: 4px; + padding: 8px 16px; font-size: 14px; + cursor: pointer; + transition: background-color 0.2s ease-in-out; +} + +.header__login:hover, +.header__create-account:hover { + background-color: #155a99; +} + +.header__logout { + background-color: #d32f2f; + color: #fff; + border: none; + border-radius: 4px; + padding: 8px 16px; + font-size: 14px; + cursor: pointer; + transition: background-color 0.2s ease-in-out; +} + +.header__logout:hover { + background-color: #b71c1c; } diff --git a/apps/web/src/components/Logo/Logo.css b/apps/web/src/components/Logo/Logo.css deleted file mode 100644 index 9fdceda..0000000 --- a/apps/web/src/components/Logo/Logo.css +++ /dev/null @@ -1 +0,0 @@ -/* Base Styles */ diff --git a/apps/web/src/components/Logo/Logo.tsx b/apps/web/src/components/Logo/Logo.tsx index 1fe3432..59b1a35 100644 --- a/apps/web/src/components/Logo/Logo.tsx +++ b/apps/web/src/components/Logo/Logo.tsx @@ -1,11 +1,48 @@ import React from "react"; -import "./Logo.css"; -export interface LogoProps extends React.HTMLAttributes {} +export interface LogoProps { + /** Width of the logo */ + width?: number; + /** Height of the logo */ + height?: number; + /** Optional additional class names for styling */ + className?: string; +} -const Logo = ({ ...props }: LogoProps) => { - const classNames = []; - return
; +const Logo: React.FC = ({ + width = "100%", + height = "100%", + className, +}) => { + return ( + + {/* Outer Circle */} + + {/* Inner Circle */} + + {/* Pointer */} + + {/* Text */} + + رنت‌منت + + + ); }; export { Logo }; diff --git a/apps/web/src/index.css b/apps/web/src/index.css index 20741bc..a8cf466 100644 --- a/apps/web/src/index.css +++ b/apps/web/src/index.css @@ -36,4 +36,5 @@ body { place-items: center; min-width: 320px; min-height: 100vh; + background-color: #f5f5f5; }