From 5c33277faef05b277d67679681029018b73e094a Mon Sep 17 00:00:00 2001 From: lewisblackburn Date: Sun, 3 Nov 2024 21:38:06 +0000 Subject: [PATCH] feat(navbar): new navbar and removed all old homepage content --- app/components/app-sidebar.tsx | 2 +- app/components/footer.tsx | 298 ++++++----------------- app/components/navigation-bar.tsx | 207 ++++++++++------ app/root.tsx | 38 +-- app/routes/_home+/index.tsx | 385 +----------------------------- app/routes/_home.tsx | 11 +- app/styles/tailwind.css | 11 +- other/svg-icons/at-sign.svg | 19 ++ other/svg-icons/binoculars.svg | 23 ++ other/svg-icons/discord-logo.svg | 9 + other/svg-icons/inbox.svg | 19 ++ other/svg-icons/mail.svg | 19 ++ other/svg-icons/map.svg | 20 ++ other/svg-icons/megaphone.svg | 19 ++ other/svg-icons/rocket.svg | 21 ++ prisma/seed.ts | 1 - 16 files changed, 397 insertions(+), 705 deletions(-) create mode 100644 other/svg-icons/at-sign.svg create mode 100644 other/svg-icons/binoculars.svg create mode 100644 other/svg-icons/discord-logo.svg create mode 100644 other/svg-icons/inbox.svg create mode 100644 other/svg-icons/mail.svg create mode 100644 other/svg-icons/map.svg create mode 100644 other/svg-icons/megaphone.svg create mode 100644 other/svg-icons/rocket.svg diff --git a/app/components/app-sidebar.tsx b/app/components/app-sidebar.tsx index 7ea767a..7833de7 100644 --- a/app/components/app-sidebar.tsx +++ b/app/components/app-sidebar.tsx @@ -27,7 +27,7 @@ import { SidebarMenuButton, SidebarMenuItem, } from '#app/components/ui/sidebar' -import { IconLogo, IconWithTextLogo } from './logo' +import { IconLogo } from './logo' import { NavMedia } from './nav-media' const data = { diff --git a/app/components/footer.tsx b/app/components/footer.tsx index 2998f41..9022a5e 100644 --- a/app/components/footer.tsx +++ b/app/components/footer.tsx @@ -1,222 +1,82 @@ -// Footer.tsx -import { Form, Link } from '@remix-run/react' -import { type SVGProps } from 'react' -import { Icon } from './ui/icon' -import { Input } from './ui/input' -import { Label } from './ui/label' - -// Define the navigation types -type NavigationItem = { - name: string - href: string - icon?: (props: SVGProps) => JSX.Element -} - -type Navigation = { - aboutus: NavigationItem[] - services: NavigationItem[] - support: NavigationItem[] - misc: NavigationItem[] - social: NavigationItem[] -} - -const navigation: Navigation = { - aboutus: [ - { name: 'Our Story', href: '#' }, - { name: 'Team', href: '#' }, - { name: 'Careers', href: '#' }, - { name: 'Contact Us', href: '#' }, - ], - services: [ - { name: 'API', href: '#' }, - { name: 'Pricing', href: '#' }, - { name: 'Documentation', href: '#' }, - { name: 'Integrations', href: '#' }, - ], - support: [ - { name: 'FAQ', href: '#' }, - { name: 'Help Center', href: '#' }, - { name: 'Terms of Service', href: '#' }, - { name: 'Privacy Policy', href: '#' }, - ], - misc: [ - { name: 'Blog', href: '#' }, - { name: 'Status', href: '#' }, - { name: 'Security', href: '#' }, - { name: 'Sitemap', href: '#' }, - ], - social: [ - { - name: 'Facebook', - href: '#', - icon: (props: SVGProps) => ( - - ), - }, - { - name: 'Instagram', - href: '#', - icon: (props: SVGProps) => ( - - ), - }, - { - name: 'Twitter', - href: '#', - icon: (props: SVGProps) => ( - - ), - }, - { - name: 'GitHub', - href: '#', - icon: (props: SVGProps) => ( - - ), - }, - { - name: 'Dribbble', - href: '#', - icon: (props: SVGProps) => ( - - ), - }, - ], -} +// // Define the navigation types +// type NavigationItem = { +// name: string +// href: string +// icon?: (props: SVGProps) => JSX.Element +// } +// +// type Navigation = { +// aboutus: NavigationItem[] +// services: NavigationItem[] +// support: NavigationItem[] +// misc: NavigationItem[] +// social: NavigationItem[] +// } +// +// const navigation: Navigation = { +// aboutus: [ +// { name: 'Our Story', href: '#' }, +// { name: 'Team', href: '#' }, +// { name: 'Careers', href: '#' }, +// { name: 'Contact Us', href: '#' }, +// ], +// services: [ +// { name: 'API', href: '#' }, +// { name: 'Pricing', href: '#' }, +// { name: 'Documentation', href: '#' }, +// { name: 'Integrations', href: '#' }, +// ], +// support: [ +// { name: 'FAQ', href: '#' }, +// { name: 'Help Center', href: '#' }, +// { name: 'Terms of Service', href: '#' }, +// { name: 'Privacy Policy', href: '#' }, +// ], +// misc: [ +// { name: 'Blog', href: '#' }, +// { name: 'Status', href: '#' }, +// { name: 'Security', href: '#' }, +// { name: 'Sitemap', href: '#' }, +// ], +// social: [ +// { +// name: 'Facebook', +// href: '#', +// icon: (props: SVGProps) => ( +// +// ), +// }, +// { +// name: 'Instagram', +// href: '#', +// icon: (props: SVGProps) => ( +// +// ), +// }, +// { +// name: 'Twitter', +// href: '#', +// icon: (props: SVGProps) => ( +// +// ), +// }, +// { +// name: 'GitHub', +// href: '#', +// icon: (props: SVGProps) => ( +// +// ), +// }, +// { +// name: 'Dribbble', +// href: '#', +// icon: (props: SVGProps) => ( +// +// ), +// }, +// ], +// } export default function Footer() { - return ( -
- -
-
-
-
-
-

- About Us -

-
    - {navigation.aboutus.map((item) => ( -
  • - - {item.name} - -
  • - ))} -
-
-
-

- Support -

-
    - {navigation.support.map((item) => ( -
  • - - {item.name} - -
  • - ))} -
-
-
-
-
-

- Services -

-
    - {navigation.services.map((item) => ( -
  • - - {item.name} - -
  • - ))} -
-
-
-

- Misc -

-
    - {navigation.misc.map((item) => ( -
  • - - {item.name} - -
  • - ))} -
-
-
-
-
-

- Subscribe to our newsletter -

-

- The latest news, articles, and resources, sent to your inbox - weekly. -

-
- - -
- -
-
-
-
-
-
- {navigation.social.map((item) => ( - - {item.name} - {item.icon && item.icon({ className: 'w-4 h-4' })} - - ))} -
-

- © {new Date().getFullYear()} Metabase, Inc. All rights - reserved. -

-
-
-
- ) + return
} diff --git a/app/components/navigation-bar.tsx b/app/components/navigation-bar.tsx index 19b4588..0b01cec 100644 --- a/app/components/navigation-bar.tsx +++ b/app/components/navigation-bar.tsx @@ -1,6 +1,9 @@ -import { Link } from '@remix-run/react' +import { invariant } from '@epic-web/invariant' +import { Link, useRouteLoaderData } from '@remix-run/react' import React from 'react' import { Icon } from '#app/components/ui/icon.tsx' +import { type loader as rootLoader } from '#app/root' +import { ThemeSwitch } from '#app/routes/resources+/theme-switch.tsx' import { cn } from '#app/utils/misc.tsx' import { IconLogo } from './logo' import { Button } from './ui/button' @@ -15,12 +18,14 @@ import { } from './ui/navigation-menu' import { type IconName } from '@/icon-name' -type NavigationLink = ( +type NavigationLink = | { name: string; href: string } - | { name: string; items: { icon: string; name: string; href: string }[] } -)[] + | { + name: string + items: { icon: IconName; colour: string; name: string; href: string }[] + } -const NavigationLinks: NavigationLink = [ +const NavigationLinks: NavigationLink[] = [ { name: 'Product', href: '/product', @@ -29,39 +34,46 @@ const NavigationLinks: NavigationLink = [ name: 'Learn', items: [ { - icon: 'tv', + icon: 'video', name: 'Tutorials', href: '/tutorials', + colour: 'text-green-500', }, { - icon: 'tv', + icon: 'lightbulb', name: 'Quick Tips', href: '/quick-tips', + colour: 'text-yellow-500', }, { - icon: 'tv', + icon: 'briefcase', name: 'Use Cases', href: '/use-cases', + colour: 'text-red-500', }, { - icon: 'tv', + icon: 'pen-tool', name: 'Blog', href: '/blog', + colour: 'text-purple-500', }, { - icon: 'tv', + icon: 'git-compare', name: 'Compare', href: '/compare', + colour: 'text-green-500', }, { - icon: 'tv', + icon: 'circle-help', name: 'Help', href: '/help', + colour: 'text-red-500', }, { - icon: 'tv', + icon: 'book', name: 'Documentation', href: '/documentation', + colour: 'text-yellow-500', }, ], }, @@ -77,29 +89,34 @@ const NavigationLinks: NavigationLink = [ name: 'Roadmap', items: [ { - icon: 'tv', + icon: 'megaphone', name: "What's new?", href: '/whats-new', + colour: 'text-blue-500', }, { - icon: 'tv', + icon: 'map', name: 'Roadmap', href: '/roadmap', + colour: 'text-green-500', }, { - icon: 'tv', + icon: 'binoculars', name: "What's next", href: '/whats-next', + colour: 'text-purple-500', }, { - icon: 'tv', + icon: 'cross-1', name: "What's not next?", href: '/whats-not-next', + colour: 'text-red-500', }, { - icon: 'tv', + icon: 'inbox', name: 'Requests, ideas, bugs', href: '/feedback', + colour: 'text-blue-500', }, ], }, @@ -107,38 +124,46 @@ const NavigationLinks: NavigationLink = [ name: 'More', items: [ { - icon: 'tv', + icon: 'discord-logo', name: 'Join our community', href: '', + colour: 'text-blue-500', }, { - icon: 'tv', + icon: 'at-sign', name: 'Newsletter', href: '', + colour: 'text-purple-500', }, { - icon: 'tv', - name: 'Carrer', + icon: 'rocket', + name: 'Career', href: '', + colour: 'text-green-500', }, { - icon: 'tv', + icon: 'mail', name: 'Contact', href: '', + colour: 'text-blue-500', }, { - icon: 'tv', + icon: 'download', name: 'Download the app', href: '', + colour: 'text-blue-500', }, ], }, ] export default function NavigationBar() { + const data = useRouteLoaderData('root') + invariant(data?.requestInfo, 'No requestInfo found in root loader') + return (
-
+
@@ -198,30 +242,53 @@ export default function NavigationBar() { ) } -const ListItem = React.forwardRef< - React.ElementRef<'a'>, - React.ComponentPropsWithoutRef<'a'> & { - title: string - icon: IconName - } ->(({ className, title, icon, ...props }, ref) => { - return ( -
  • - - + +const ListItem = React.forwardRef( + ( + { className, title, href, icon, colour, isFooter = false, ...props }, + ref, + ) => { + return ( +
  • + + {!isFooter ? ( + + +
    + {title} +
    +
    + ) : ( + +
    +
    + +
    + {title} +
    +
    +
    +
    )} - {...props} - > - -
    {title}
    - - -
  • - ) -}) + + + ) + }, +) -ListItem.displayName = 'ListItem' +ListItem.displayName diff --git a/app/root.tsx b/app/root.tsx index fdb0621..4398107 100644 --- a/app/root.tsx +++ b/app/root.tsx @@ -80,28 +80,28 @@ export async function loader({ request }: LoaderFunctionArgs) { const user = userId ? await time( - () => - prisma.user.findUniqueOrThrow({ - select: { - id: true, - name: true, - username: true, - email: true, - image: { select: { id: true } }, - initials: true, - roles: { - select: { - name: true, - permissions: { - select: { entity: true, action: true, access: true }, + () => + prisma.user.findUniqueOrThrow({ + select: { + id: true, + name: true, + username: true, + email: true, + image: { select: { id: true } }, + initials: true, + roles: { + select: { + name: true, + permissions: { + select: { entity: true, action: true, access: true }, + }, }, }, }, - }, - where: { id: userId }, - }), - { timings, type: 'find user', desc: 'find user in root' }, - ) + where: { id: userId }, + }), + { timings, type: 'find user', desc: 'find user in root' }, + ) : null if (userId && !user) { console.info('something weird happened') diff --git a/app/routes/_home+/index.tsx b/app/routes/_home+/index.tsx index 759d587..87ffa09 100644 --- a/app/routes/_home+/index.tsx +++ b/app/routes/_home+/index.tsx @@ -1,388 +1,7 @@ import { type MetaFunction } from '@remix-run/node' -import { Link } from '@remix-run/react' -import Autoscroll from 'embla-carousel-auto-scroll' -import { useEffect, useState } from 'react' -import { Button } from '#app/components/ui/button.js' -import { - Carousel, - CarouselContent, - CarouselItem, -} from '#app/components/ui/carousel.js' -import { Icon } from '#app/components/ui/icon.js' + export const meta: MetaFunction = () => [{ title: 'Metabase' }] export default function HomePage() { - const [isVisible, setIsVisible] = useState(false) - - useEffect(() => { - const timer = setTimeout(() => { - setIsVisible(true) - }, 100) // Short delay to allow styles to apply correctly - return () => clearTimeout(timer) - }, []) - - return ( -
    -
    -
    - - -
    -
    - - - -
    - ) -} - -function Hero() { - return ( -
    -
    -

    - Linking Worlds{' '} - - Through Stories - -

    -

    - Discover the connections between films, songs, games, books, and the - people who bring them to life. -

    -
    - - - - - -
    -
    -
    - ) -} - -const Logos = [ - { - name: 'TMDB', - url: 'https://www.themoviedb.org/', - image: '/images/logos/tmdb.png', - }, - { - name: 'Spotify', - url: 'https://www.spotify.com/', - image: '/images/logos/spotify.png', - }, - { - name: 'Steam', - url: 'https://store.steampowered.com/', - image: '/images/logos/steam.png', - }, - { - name: 'Goodreads', - url: 'https://www.goodreads.com/', - image: '/images/logos/goodreads.png', - }, - { - name: 'IMDb', - url: 'https://www.imdb.com/', - image: '/images/logos/imdb.png', - }, -] - -function LogoCloud() { - return ( -
    -
    - {}, // Disable drag - loop: true, - }} - plugins={[Autoscroll({ startDelay: 0 })]} - > - - {[...Logos, ...Logos, ...Logos].map((logo, index) => ( - - - {logo.name} - - - ))} - - -
    -
    - ) -} - -// function LogoCloud() { -// return ( -//
    -//
    -//
    -// {Logos.map((logo) => ( -//
    -// -// {logo.name} -// -//
    -// ))} -//
    -//
    -//
    -// ) -// } - -function Feature() { - return ( -
    -
    -
    -
    -
    -
    - - -
    -
    -

    - Stay on top of your favourite media -

    -

    - The Metabase database is constantly updated with new - information about films, soundtracks, games, books, and - people. You can follow your favorite entries to receive - notifications when new information is added or updated. -

    -
    - - Get started - -
    -
    -
    -
    -
    -
    -

    - “I wanted to create a platform where users could - explore these connections and discover new ways to enjoy - their favorite films, songs, games, and books.” -

    -
    -
    -
    -
    - -
    -
    - Lewis Blackburn, Founder of Metabase -
    -
    -
    -
    -
    -
    -
    -
    - Inbox user interface -
    -
    -
    -
    -
    -
    -
    -
    -
    - - -
    -
    -

    - Manage your media better -

    -

    - The dashboard offers all the tools you need to manage your - favorite media, allowing you to edit and create content while - keeping you updated with the latest developments. -

    -
    - - Get started - -
    -
    -
    -
    -
    -
    - Customer profile user interface -
    -
    -
    -
    -
    - ) -} - -function Statistics() { - return ( -
    -
    -
    -

    - Largest media database on the web -

    -

    - The Metabase database is the largest, most comprehensive collection - of media information on the web. -

    -
    -
    -
    -
    -
    -
    -
    -
    -
    - Up-Time -
    -
    - 100% -
    -
    -
    -
    - Entries -
    -
    - 1M -
    -
    -
    -
    - Users -
    -
    - 100k -
    -
    -
    -
    -
    -
    -
    -
    - ) -} - -const faqs = [ - { - question: 'What is Metabase?', - answer: - 'Metabase is a comprehensive database that connects and provides detailed information about films, soundtracks, people (actors, artists), games, and books. You can explore connections between various forms of media and discover how they relate to one another.', - }, - { - question: 'How can I contribute to Metabase?', - answer: - 'You can contribute to Metabase by adding new entries, editing existing entries, and connecting entries to show relationships between them. You can also help by adding missing information, such as cast members, release dates, and more.', - }, - { - question: 'How do I get started with Metabase?', - answer: - 'To get started with Metabase, create an account and start exploring the database. You can search for your favorite films, songs, games, books, and people, and discover how they are connected. You can also contribute by adding new entries or editing existing ones.', - }, -] - -function FAQ() { - return ( -
    -
    -
    -
    -

    - Frequently asked questions -

    -

    - Can’t find the answer you’re looking for? Reach out to our{' '} - - customer support - {' '} - team. -

    -
    -
    -
    - {faqs.map((faq) => ( -
    -
    - {faq.question} -
    -
    {faq.answer}
    -
    - ))} -
    -
    -
    -
    -
    - ) + return
    } diff --git a/app/routes/_home.tsx b/app/routes/_home.tsx index d50f4b0..05c28e2 100644 --- a/app/routes/_home.tsx +++ b/app/routes/_home.tsx @@ -1,14 +1,8 @@ -import { invariant } from '@epic-web/invariant' -import { Outlet, useRouteLoaderData } from '@remix-run/react' +import { Outlet } from '@remix-run/react' import Footer from '#app/components/footer.js' import NavigationBar from '#app/components/navigation-bar.js' -import { type loader as rootLoader } from '#app/root' -import { ThemeSwitch } from './resources+/theme-switch' export default function HomePageLayout() { - const data = useRouteLoaderData('root') - invariant(data?.requestInfo, 'No requestInfo found in root loader') - return (
    @@ -18,9 +12,6 @@ export default function HomePageLayout() {
    -
    - -
    ) } diff --git a/app/styles/tailwind.css b/app/styles/tailwind.css index 6fdd86b..59b68e1 100644 --- a/app/styles/tailwind.css +++ b/app/styles/tailwind.css @@ -44,7 +44,6 @@ --chart-3: 216 92% 60%; --chart-4: 210 98% 78%; --chart-5: 212 97% 87%; - --sidebar-background: 0 0% 98%; --sidebar-foreground: 240 5.3% 26.1%; --sidebar-primary: 240 5.9% 10%; @@ -95,7 +94,6 @@ --chart-3: 216 92% 60%; --chart-4: 210 98% 78%; --chart-5: 212 97% 87%; - --sidebar-background: 240 5.9% 10%; --sidebar-foreground: 240 4.8% 95.9%; --sidebar-primary: 224.3 76.3% 48%; @@ -106,3 +104,12 @@ --sidebar-ring: 217.2 91.2% 59.8%; } } + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/other/svg-icons/at-sign.svg b/other/svg-icons/at-sign.svg new file mode 100644 index 0000000..96de3dd --- /dev/null +++ b/other/svg-icons/at-sign.svg @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/other/svg-icons/binoculars.svg b/other/svg-icons/binoculars.svg new file mode 100644 index 0000000..443daed --- /dev/null +++ b/other/svg-icons/binoculars.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + diff --git a/other/svg-icons/discord-logo.svg b/other/svg-icons/discord-logo.svg new file mode 100644 index 0000000..cb55296 --- /dev/null +++ b/other/svg-icons/discord-logo.svg @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/other/svg-icons/inbox.svg b/other/svg-icons/inbox.svg new file mode 100644 index 0000000..a3f4f18 --- /dev/null +++ b/other/svg-icons/inbox.svg @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/other/svg-icons/mail.svg b/other/svg-icons/mail.svg new file mode 100644 index 0000000..72a6cb9 --- /dev/null +++ b/other/svg-icons/mail.svg @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/other/svg-icons/map.svg b/other/svg-icons/map.svg new file mode 100644 index 0000000..92a4f91 --- /dev/null +++ b/other/svg-icons/map.svg @@ -0,0 +1,20 @@ + + + + + + + + + + diff --git a/other/svg-icons/megaphone.svg b/other/svg-icons/megaphone.svg new file mode 100644 index 0000000..33450ef --- /dev/null +++ b/other/svg-icons/megaphone.svg @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/other/svg-icons/rocket.svg b/other/svg-icons/rocket.svg new file mode 100644 index 0000000..ef76325 --- /dev/null +++ b/other/svg-icons/rocket.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/prisma/seed.ts b/prisma/seed.ts index 37f6262..03448c8 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -35,7 +35,6 @@ async function seed() { console.timeEnd(`🌱 Database has been seeded`) } - async function createUsers() { const totalUsers = 5 console.time(`👤 Created ${totalUsers} users...`)