Skip to content
This repository has been archived by the owner on Dec 10, 2024. It is now read-only.

Commit

Permalink
add(nextjs): complete landing page design
Browse files Browse the repository at this point in the history
  • Loading branch information
saeidex committed Sep 25, 2024
1 parent b16522a commit 4831be2
Show file tree
Hide file tree
Showing 15 changed files with 437 additions and 25 deletions.
3 changes: 3 additions & 0 deletions apps/nextjs/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ const config = {
experimental: {
typedRoutes: true,
},
images: {
remotePatterns: [{ hostname: "github.com", protocol: "https" }],
},

/** Enables hot reloading for local packages without a build step */
transpilePackages: [
Expand Down
2 changes: 2 additions & 0 deletions apps/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
},
"prettier": "@ubus/prettier-config",
"dependencies": {
"@conform-to/react": "^1.2.2",
"@conform-to/zod": "^1.2.2",
"@t3-oss/env-nextjs": "^0.11.0",
"@tabler/icons-react": "^3.17.0",
"@tanstack/react-query": "catalog:",
Expand Down
1 change: 1 addition & 0 deletions apps/nextjs/public/hey.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion apps/nextjs/src/app/(landing)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const LandingPageLayout = (props: { children: React.ReactNode }) => {
return (
<>
<Navbar />
<main>{props.children}</main>
<main className="mx-auto h-full w-full">{props.children}</main>
<Footer />
</>
);
Expand Down
100 changes: 98 additions & 2 deletions apps/nextjs/src/app/_components/contact.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,101 @@
import React from "react";
import Image from "next/image";

import { cn } from "@ubus/ui";
import { Button } from "@ubus/ui/button";
import { Input } from "@ubus/ui/input";
import { Label } from "@ubus/ui/label";
import { Textarea } from "@ubus/ui/textarea";

interface IFromItem {
label: string;
name: string;
placholder: string;
}

const formItems: IFromItem[] = [
{
label: "First name",
name: "first_name",
placholder: "First name",
},
{
label: "Last name",
name: "last_name",
placholder: "Last name",
},
{
label: "Email",
name: "email",
placholder: "[email protected]",
},
{
label: "Phone (Optional)",
name: "phone",
placholder: "01400-12345",
},
];

export const Contact = () => {
return <div>Contact</div>;
return (
<div className="container my-16 flex flex-col gap-8 lg:my-32 lg:gap-24">
<div className="flex flex-col gap-3">
<h2 className="text-center text-headline-large font-bold md:text-display-large">
Contact our team
</h2>
<p className="text-center text-body-small md:text-headline-small">
Got any questions about the product or scaling on our platform?
</p>
</div>
<div className="lg:grid lg:grid-cols-2 lg:gap-20">
<div className="grid grid-cols-1 gap-5 lg:grid-cols-2 lg:gap-8">
{formItems.map((item) => (
<FormInput key={item.name} formItem={item} />
))}
<div className="flex flex-col gap-3 lg:col-span-2">
<Label className="text-xl" htmlFor="message">
Message
</Label>
<Textarea
className="col-span-2 border-outline bg-surface-container-low text-xl text-outline placeholder:text-xl placeholder:text-outline/30"
rows={10}
name="message"
placeholder="Leave us a message..."
/>
</div>
<Button className="h-[52px] text-xl font-medium lg:col-span-2">
Send Message
</Button>
</div>
<div className="hidden rounded-3xl lg:block">
<Image
alt="contact form banner image"
src={"hey.svg"}
width={1024}
height={2048}
className="h-full w-full"
/>
</div>
</div>
</div>
);
};

const FormInput = ({ formItem }: { formItem: IFromItem }) => {
return (
<div
className={cn(
"flex flex-col gap-3 lg:col-span-2",
formItem.name.includes("name") && "lg:col-span-1",
)}
>
<Label className="text-xl" htmlFor={formItem.name}>
{formItem.label}
</Label>
<Input
className="h-[52px] border-outline bg-surface-container-low text-xl text-outline placeholder:text-xl placeholder:text-outline/30"
name={formItem.name}
placeholder={formItem.placholder}
/>
</div>
);
};
10 changes: 5 additions & 5 deletions apps/nextjs/src/app/_components/features.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,18 @@ const keyFeatures = [

export const KeyFeatures = () => {
return (
<div className="grid grid-cols-2 items-center py-8">
<div className="container grid grid-cols-2 items-center py-8">
<h2 className="text-headline-large font-bold leading-7 sm:text-display-medium lg:self-end">
Discover the key benefits
</h2>
<Image
alt="bus picture"
className="h-36 lg:row-span-2 lg:h-auto xl:row-span-3 xl:pl-4"
className="h-36 w-fit lg:row-span-2 lg:h-auto xl:row-span-3 xl:pl-4"
src={"/bus.svg"}
height={563}
width={699}
/>
<p className="col-span-2 sm:pb-4 sm:text-headline-medium lg:col-span-1 lg:self-start lg:pb-0 lg:pt-4">
<p className="col-span-2 sm:pb-4 sm:text-headline-medium md:pb-12 lg:col-span-1 lg:self-start lg:pb-0 lg:pt-4">
Track buses in real-time and get instant notifications, all from an
easy-to-use dashboard.
</p>
Expand Down Expand Up @@ -87,11 +87,11 @@ const essentialFeatures = [

export const EssentialFeatures = () => {
return (
<div className="grid gap-3 py-8 lg:my-32 lg:grid-cols-6 lg:gap-y-12">
<div className="container grid gap-3 py-8 lg:my-32 lg:grid-cols-6 lg:gap-y-12">
<h2 className="text-headline-large font-bold leading-7 sm:text-display-medium lg:col-span-3 lg:self-end">
Explore Our Essential Bus Tracking Features
</h2>
<p className="pb-4 text-justify text-body-large md:pb-6 lg:col-span-3 lg:pb-0 lg:text-base">
<p className="text-balance pb-4 text-body-large md:pb-6 lg:col-span-3 lg:pb-0 lg:text-justify lg:text-base">
Our bus tracking system offers three key features designed for student
convenience. Access real-time bus locations, view schedules, and stay
updated on important announcements all in one place. Experience seamless
Expand Down
137 changes: 136 additions & 1 deletion apps/nextjs/src/app/_components/footer.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,138 @@
"use client";

import Image from "next/image";
import Link from "next/link";

import useThemeBasedValue from "@ubus/hooks/useThemeBasedValue";
import { Separator } from "@ubus/ui/separator";

export interface IMenuItem {
title: string;
links: {
label: string;
href: string;
}[];
}

const footerMenuItems: IMenuItem[] = [
{
title: "Resources",
links: [
{
label: "Newsletter",
href: "",
},
{
label: "Blog",
href: "",
},
{
label: "Support",
href: "",
},
],
},
{
title: "Socials",
links: [
{
label: "Facebook",
href: "",
},
{
label: "LinkedIn",
href: "",
},
{
label: "GitHub",
href: "",
},
],
},
{
title: "Important",
links: [
{
label: "Settings",
href: "",
},
{
label: "Contact",
href: "",
},
],
},
{
title: "Legals",
links: [
{
label: "License",
href: "",
},
{
label: "Privacy",
href: "",
},
],
},
];

export const Footer = () => {
return <div>Footer</div>;
const logoSrc = useThemeBasedValue("ubus.svg", "ubus-dark.svg");
return (
<div className="border-t border-outline-variant bg-surface-dim py-8 pt-12 lg:pt-20">
<div className="container flex flex-col gap-2">
<div className="flex flex-col gap-9">
<div className="flex flex-col gap-4">
<Link
href="/"
className="flex items-center space-x-3 rtl:space-x-reverse"
>
<Image
src={logoSrc}
width={32}
height={24}
className="h-8 w-6"
alt="ubus logo"
/>
<span className="self-center whitespace-nowrap text-headline-large font-semibold dark:text-white">
UBus
</span>
</Link>
<p className="text-body-large sm:text-headline-small">
Access live bus locations, schedules, and important updates all in
one place.
</p>
</div>
<div className="grid gap-9 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
{footerMenuItems.map((item) => (
<FooterMenu menu={item} />
))}
</div>
<Separator />
</div>
<p className="text-label-small text-on-surface/40 md:text-label-large">
Copyright 2024. All right reserved.
</p>
</div>
</div>
);
};

const FooterMenu = ({ menu }: { menu: IMenuItem }) => {
return (
<div className="flex flex-col gap-1">
<h3 className="text-headline-small text-outline">{menu.title}</h3>
<div className="flex flex-col items-start">
{menu.links.map((link) => (
<Link
className="text-headline-large hover:underline"
href={{ href: link.href }}
>
{link.label}
</Link>
))}
</div>
</div>
);
};
2 changes: 1 addition & 1 deletion apps/nextjs/src/app/_components/hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const Hero = ({ className }: { className?: string }) => {
return (
<section
className={cn(
"grid lg:container md:py-8 lg:min-h-[calc(100dvh-6rem)] lg:px-12",
"container grid md:py-8 lg:min-h-[calc(100dvh-6rem)] lg:px-20",
className,
)}
>
Expand Down
2 changes: 1 addition & 1 deletion apps/nextjs/src/app/_components/navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const Navbar = () => {
const logoSrc = useThemeBasedValue("ubus.svg", "ubus-dark.svg");

return (
<nav className="border-outline">
<nav className="container border-outline">
<div className="mx-auto flex h-24 flex-wrap items-center justify-between">
<Link
href="/"
Expand Down
Loading

0 comments on commit 4831be2

Please sign in to comment.