Navigation done

This commit is contained in:
Fergal Moran
2023-05-27 19:43:31 +01:00
parent 6a96107559
commit e9cd73f1e7
20 changed files with 1656 additions and 371 deletions

View File

@@ -24,7 +24,6 @@
"@trpc/server": "^10.26.0",
"argon2": "^0.30.3",
"classnames": "^2.3.2",
"flowbite-react": "^0.4.4",
"http-status-codes": "^2.2.0",
"install": "^0.13.0",
"next": "13.4.2",
@@ -41,6 +40,9 @@
},
"devDependencies": {
"@faker-js/faker": "^8.0.0",
"@radix-ui/react-avatar": "^1.0.3",
"@radix-ui/react-dropdown-menu": "^2.0.5",
"@radix-ui/react-slot": "^1.0.2",
"@types/eslint": "^8.37.0",
"@types/node": "^20.1.4",
"@types/prettier": "^2.7.2",
@@ -51,12 +53,16 @@
"@typescript-eslint/eslint-plugin": "^5.59.5",
"@typescript-eslint/parser": "^5.59.5",
"autoprefixer": "^10.4.14",
"class-variance-authority": "^0.6.0",
"clsx": "^1.2.1",
"concurrently": "^8.0.1",
"dayjs": "^1.11.7",
"eslint": "^8.40.0",
"eslint-config-next": "^13.4.2",
"formik": "^2.2.9",
"hls.js": "^1.4.3",
"lucide-react": "^0.221.0",
"next-themes": "^0.2.1",
"postcss": "^8.4.23",
"prettier": "^2.8.8",
"prettier-plugin-tailwindcss": "^0.2.8",
@@ -67,7 +73,9 @@
"react-dropzone": "^14.2.3",
"retry": "^0.13.1",
"superagent": "^8.0.9",
"tailwind-merge": "^1.12.0",
"tailwindcss": "^3.3.2",
"tailwindcss-animate": "^1.0.5",
"typescript": "^5.0.4",
"uuid": "^9.0.0"
},

1011
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,5 @@
"use client";
import { api } from "@/lib/utils/api";
import { Flowbite } from "flowbite-react";
import { SessionProvider } from "next-auth/react";
import React from "react";
@@ -8,11 +7,7 @@ type ProvidersProps = {
children: React.ReactNode;
};
const Providers = ({ children }: ProvidersProps) => {
return (
<SessionProvider>
<Flowbite theme={{}}>{children}</Flowbite>
</SessionProvider>
);
return <SessionProvider>{children}</SessionProvider>;
};
export default api.withTRPC(Providers);

View File

@@ -1,3 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@@ -1,7 +1,8 @@
import Navbar from "@/lib/components/layout/Navbar";
import "./globals.css";
import "../styles/globals.css";
import Providers from "./Providers";
import { Raleway } from "next/font/google";
import Image from "next/image";
const font = Raleway({
subsets: ["latin"],
@@ -13,8 +14,28 @@ const RootLayout = ({ children }: { children: React.ReactNode }) => {
<html lang="en" className={font.className}>
<body>
<Providers>
<Navbar />
<div className="bg-gray-50 pt-16 dark:bg-gray-900">{children}</div>
<div className="md:hidden">
<Image
src="/examples/dashboard-light.png"
width={1280}
height={866}
alt="Dashboard"
className="block dark:hidden"
/>
<Image
src="/examples/dashboard-dark.png"
width={1280}
height={866}
alt="Dashboard"
className="hidden dark:block"
/>
</div>
<div className="hidden flex-col md:flex">
<div className="border-b">
<Navbar className="mx-6" />
</div>
<div className="flex-1 space-y-4 p-8 pt-6">{children}</div>
</div>
</Providers>
</body>
</html>

View File

@@ -0,0 +1,49 @@
"use client";
import * as React from "react";
import * as AvatarPrimitive from "@radix-ui/react-avatar";
import { cn } from "@/lib/utils/styles";
const Avatar = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Root
ref={ref}
className={cn(
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
className
)}
{...props}
/>
));
Avatar.displayName = AvatarPrimitive.Root.displayName;
const AvatarImage = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Image>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Image
ref={ref}
className={cn("aspect-square h-full w-full", className)}
{...props}
/>
));
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
const AvatarFallback = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Fallback>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Fallback
ref={ref}
className={cn(
"flex h-full w-full items-center justify-center rounded-full bg-muted",
className
)}
{...props}
/>
));
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
export { Avatar, AvatarImage, AvatarFallback };

View File

@@ -0,0 +1,54 @@
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils/styles";
const buttonVariants = cva(
"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border border-input hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "underline-offset-4 hover:underline text-primary",
},
size: {
default: "h-10 py-2 px-4",
sm: "h-9 px-3 rounded-md",
lg: "h-11 px-8 rounded-md",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
);
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button";
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
);
}
);
Button.displayName = "Button";
export { Button, buttonVariants };

View File

@@ -0,0 +1,199 @@
"use client";
import * as React from "react";
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
import { Check, ChevronRight, Circle } from "lucide-react";
import { cn } from "@/lib/utils/styles";
const DropdownMenu = DropdownMenuPrimitive.Root;
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
const DropdownMenuGroup = DropdownMenuPrimitive.Group;
const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
const DropdownMenuSub = DropdownMenuPrimitive.Sub;
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
const DropdownMenuSubTrigger = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
inset?: boolean;
}
>(({ className, inset, children, ...props }, ref) => (
<DropdownMenuPrimitive.SubTrigger
ref={ref}
className={cn(
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
inset && "pl-8",
className
)}
{...props}
>
{children}
<ChevronRight className="ml-auto h-4 w-4" />
</DropdownMenuPrimitive.SubTrigger>
));
DropdownMenuSubTrigger.displayName =
DropdownMenuPrimitive.SubTrigger.displayName;
const DropdownMenuSubContent = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
>(({ className, ...props }, ref) => (
<DropdownMenuPrimitive.SubContent
ref={ref}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1",
className
)}
{...props}
/>
));
DropdownMenuSubContent.displayName =
DropdownMenuPrimitive.SubContent.displayName;
const DropdownMenuContent = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
>(({ className, sideOffset = 4, ...props }, ref) => (
<DropdownMenuPrimitive.Portal>
<DropdownMenuPrimitive.Content
ref={ref}
sideOffset={sideOffset}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className
)}
{...props}
/>
</DropdownMenuPrimitive.Portal>
));
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
const DropdownMenuItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
inset?: boolean;
}
>(({ className, inset, ...props }, ref) => (
<DropdownMenuPrimitive.Item
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
inset && "pl-8",
className
)}
{...props}
/>
));
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
const DropdownMenuCheckboxItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
>(({ className, children, checked, ...props }, ref) => (
<DropdownMenuPrimitive.CheckboxItem
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className
)}
checked={checked}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<DropdownMenuPrimitive.ItemIndicator>
<Check className="h-4 w-4" />
</DropdownMenuPrimitive.ItemIndicator>
</span>
{children}
</DropdownMenuPrimitive.CheckboxItem>
));
DropdownMenuCheckboxItem.displayName =
DropdownMenuPrimitive.CheckboxItem.displayName;
const DropdownMenuRadioItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
>(({ className, children, ...props }, ref) => (
<DropdownMenuPrimitive.RadioItem
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className
)}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<DropdownMenuPrimitive.ItemIndicator>
<Circle className="h-2 w-2 fill-current" />
</DropdownMenuPrimitive.ItemIndicator>
</span>
{children}
</DropdownMenuPrimitive.RadioItem>
));
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
const DropdownMenuLabel = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
inset?: boolean;
}
>(({ className, inset, ...props }, ref) => (
<DropdownMenuPrimitive.Label
ref={ref}
className={cn(
"px-2 py-1.5 text-sm font-semibold",
inset && "pl-8",
className
)}
{...props}
/>
));
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
const DropdownMenuSeparator = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
>(({ className, ...props }, ref) => (
<DropdownMenuPrimitive.Separator
ref={ref}
className={cn("-mx-1 my-1 h-px bg-muted", className)}
{...props}
/>
));
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
const DropdownMenuShortcut = ({
className,
...props
}: React.HTMLAttributes<HTMLSpanElement>) => {
return (
<span
className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
{...props}
/>
);
};
DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
export {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuCheckboxItem,
DropdownMenuRadioItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuGroup,
DropdownMenuPortal,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuRadioGroup,
};

View File

@@ -0,0 +1,24 @@
import { cn } from "@/lib/utils/styles";
import * as React from "react";
export interface InputProps
extends React.InputHTMLAttributes<HTMLInputElement> {}
const Input = React.forwardRef<HTMLInputElement, InputProps>(
({ className, type, ...props }, ref) => {
return (
<input
type={type}
className={cn(
"flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
ref={ref}
{...props}
/>
);
}
);
Input.displayName = "Input";
export { Input };

View File

@@ -0,0 +1,43 @@
"use client";
import * as React from "react";
import { useTheme } from "next-themes";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Icons } from "@/components/icons";
export function ModeToggle() {
const { setTheme } = useTheme();
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="sm" className="w-9 px-0">
<Icons.sun className="rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Icons.moon className="absolute rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme("light")}>
<Icons.sun className="mr-2 h-4 w-4" />
<span>Light</span>
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("dark")}>
<Icons.moon className="mr-2 h-4 w-4" />
<span>Dark</span>
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("system")}>
<Icons.laptop className="mr-2 h-4 w-4" />
<span>System</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}

View File

@@ -0,0 +1,14 @@
import { Input } from "@/components/ui/input";
const Search = () => {
return (
<div>
<Input
type="search"
placeholder="Search..."
className="h-9 md:w-[100px] lg:w-[300px]"
/>
</div>
);
};
export default Search;

View File

@@ -0,0 +1,67 @@
import { CreditCard, LogOut, PlusCircle, Settings, User } from "lucide-react";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
export function UserNav() {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="relative h-8 w-8 rounded-full">
<Avatar className="h-8 w-8">
<AvatarImage src="/avatars/01.png" alt="@shadcn" />
<AvatarFallback>SC</AvatarFallback>
</Avatar>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56" align="end" forceMount>
<DropdownMenuLabel className="font-normal">
<div className="flex flex-col space-y-1">
<p className="text-sm font-medium leading-none">shadcn</p>
<p className="text-xs leading-none text-muted-foreground">
m@example.com
</p>
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<User className="mr-2 h-4 w-4" />
<span>Profile</span>
<DropdownMenuShortcut>P</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<CreditCard className="mr-2 h-4 w-4" />
<span>Billing</span>
<DropdownMenuShortcut>B</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<Settings className="mr-2 h-4 w-4" />
<span>Settings</span>
<DropdownMenuShortcut>S</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<PlusCircle className="mr-2 h-4 w-4" />
<span>New Team</span>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>
<LogOut className="mr-2 h-4 w-4" />
<span>Log out</span>
<DropdownMenuShortcut>Q</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}

View File

@@ -1,126 +1,184 @@
"use client";
import React from "react";
import { GiHamburgerMenu } from "react-icons/gi";
import { RiFindReplaceLine } from "react-icons/ri";
import { AiOutlineClose, AiOutlineLogin } from "react-icons/ai";
import { GoBroadcast } from "react-icons/go";
import { MdOutlineCloudUpload } from "react-icons/md";
import { BsSearch } from "react-icons/bs";
import Link from "next/link";
import Image from "next/image";
import NavLink from "../widgets/NavLink";
import { usePathname } from "next/navigation";
import { useSession } from "next-auth/react";
import ProfileDropdown from "@/lib/components/widgets/ProfileDropdown";
import { Session } from "next-auth";
import Loading from "../widgets/Loading";
import { cn } from "@/lib/utils/styles";
import Search from "@/components/widgets/search";
import { UserNav } from "@/components/widgets/user-nav";
const NavbarLogin = ({
session,
status,
}: {
session: Session | null;
status: "authenticated" | "loading" | "unauthenticated";
}) => {
if (status === "loading") return <Loading />;
// const NavbarLogin = ({
// session,
// status,
// }: {
// session: Session | null;
// status: "authenticated" | "loading" | "unauthenticated";
// }) => {
// if (status === "loading") return <Loading />;
return session ? (
<ProfileDropdown session={session} />
) : (
<NavLink
title="Login"
href="/auth/login"
icon={
<AiOutlineLogin className="text-cerise-800 leading-lg text-lg opacity-75 dark:text-slate-300" />
}
/>
);
};
// return session ? (
// <ProfileDropdown session={session} />
// ) : (
// <NavLink
// title="Login"
// href="/auth/login"
// icon={
// <AiOutlineLogin className="text-cerise-800 leading-lg text-lg opacity-75 dark:text-slate-300" />
// }
// />
// );
// };
const Navbar = () => {
const Navbar = ({ className, ...props }: React.HTMLAttributes<HTMLElement>) => {
const { data: session, status } = useSession();
const path = usePathname();
console.log("Navbar", "path", path);
return (
<nav className="fixed z-30 w-full border-b border-gray-200 bg-white dark:border-gray-700 dark:bg-slate-800">
<div className="px-3 py-3 lg:px-5 lg:pl-3">
<div className="flex items-center justify-between">
<div className="flex items-center justify-start">
<button
title="Sidebar toggler"
id="toggleSidebarMobile"
aria-expanded="true"
className="cursor-pointer rounded p-2 text-gray-600 hover:bg-gray-100 hover:text-gray-900 focus:bg-gray-100 focus:ring-2 focus:ring-gray-100 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white dark:focus:bg-gray-700 dark:focus:ring-gray-700 lg:hidden"
>
<GiHamburgerMenu className="h-6 w-6" fill="currentColor" />
<AiOutlineClose
id="toggleSidebarMobileClose"
className="hidden h-6 w-6"
fill="currentColor"
/>
</button>
<Link
href="/"
className="ml-2 flex justify-center align-middle md:mr-24"
<div className="flex h-16 items-center px-4">
<nav
className={cn("flex items-center space-x-4 lg:space-x-6", className)}
{...props}
>
<a className="mr-6 flex items-center space-x-2" href="/">
<Image
className="mr-2 h-8 w-auto"
className="mr-2 h-6 w-6"
src="/img/logo.svg"
alt="Mixyboos"
width={32}
height={32}
width={24}
height={24}
/>
<span className=" whitespace-nowrap text-xl font-semibold dark:text-white sm:text-2xl">
MixyBoos
<span className="hidden font-bold lowercase sm:inline-block">
Mixy/Boos
</span>
</Link>
</div>
<div className="mr-4 flex flex-row space-x-2">
<NavLink
title="Discover"
</a>
<Link
href="/discover"
icon={
<RiFindReplaceLine className="text-cerise-800 leading-lg text-lg opacity-75 dark:text-slate-300" />
}
/>
<NavLink
title="Go Live"
href="/live/create"
icon={
<GoBroadcast className="text-cerise-800 leading-lg text-lg opacity-75 dark:text-slate-300" />
}
/>
<NavLink
title="Upload"
href="/mix/create"
icon={
<MdOutlineCloudUpload className="text-cerise-800 leading-lg text-lg opacity-75 dark:text-slate-300" />
}
/>
</div>
<div className="flex items-center">
<div className="-mb-1 mr-3 hidden sm:block">
<span />
</div>
<button
id="toggleSidebarMobileSearch"
type="button"
className="rounded-lg p-2 text-gray-500 hover:bg-gray-100 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white lg:hidden"
className={cn(
"text-sm font-medium lowercase transition-colors hover:text-primary",
path !== "/discover" && "text-muted-foreground"
)}
>
<span className="sr-only">Search</span>
<BsSearch
className="h-6 w-6 text-gray-500 dark:text-gray-400"
fill="currentColor"
/>
</button>
{/* {session && <NotificationsDropdownComponent session={session} />}
{false && <AppsDropdownComponent />}
<ThemeToggler />
{session && <ProfileDropdown session={session} />} */}
<NavbarLogin session={session} status={status} />
</div>
</div>
</div>
Discover
</Link>
<Link
href="/live/create"
className={cn(
"text-sm font-medium lowercase transition-colors hover:text-primary",
path !== "/live/create" && "text-muted-foreground"
)}
>
Go live
</Link>
<Link
href="/mix/create"
className={cn(
"text-sm font-medium lowercase transition-colors hover:text-primary",
path !== "/mix/create" && "text-muted-foreground"
)}
>
Upload
</Link>
<Link
href="/calendar"
className={cn(
"text-sm font-medium lowercase transition-colors hover:text-primary",
path !== "/calendar" && "text-muted-foreground"
)}
>
Upcoming
</Link>
</nav>
<div className="ml-auto flex items-center space-x-4">
<Search />
<UserNav />
</div>
</div>
// <nav className="fixed z-30 w-full border-b border-gray-200 bg-white dark:border-gray-700 dark:bg-slate-800">
// <div className="px-3 py-3 lg:px-5 lg:pl-3">
// <div className="flex items-center justify-between">
// <div className="flex items-center justify-start">
// <button
// title="Sidebar toggler"
// id="toggleSidebarMobile"
// aria-expanded="true"
// className="cursor-pointer rounded p-2 text-gray-600 hover:bg-gray-100 hover:text-gray-900 focus:bg-gray-100 focus:ring-2 focus:ring-gray-100 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white dark:focus:bg-gray-700 dark:focus:ring-gray-700 lg:hidden"
// >
// <GiHamburgerMenu className="h-6 w-6" fill="currentColor" />
// <AiOutlineClose
// id="toggleSidebarMobileClose"
// className="hidden h-6 w-6"
// fill="currentColor"
// />
// </button>
// <Link
// href="/"
// className="ml-2 flex justify-center align-middle md:mr-24"
// >
// <Image
// className="mr-2 h-8 w-auto"
// src="/img/logo.svg"
// alt="Mixyboos"
// width={32}
// height={32}
// />
// <span className=" whitespace-nowrap text-xl font-semibold dark:text-white sm:text-2xl">
// MixyBoos
// </span>
// </Link>
// </div>
// <div className="mr-4 flex flex-row space-x-2">
// <NavLink
// title="Discover"
// href="/discover"
// icon={
// <RiFindReplaceLine className="text-cerise-800 leading-lg text-lg opacity-75 dark:text-slate-300" />
// }
// />
// <NavLink
// title="Go Live"
// href="/live/create"
// icon={
// <GoBroadcast className="text-cerise-800 leading-lg text-lg opacity-75 dark:text-slate-300" />
// }
// />
// <NavLink
// title="Upload"
// href="/mix/create"
// icon={
// <MdOutlineCloudUpload className="text-cerise-800 leading-lg text-lg opacity-75 dark:text-slate-300" />
// }
// />
// </div>
// <div className="flex items-center">
// <div className="-mb-1 mr-3 hidden sm:block">
// <span />
// </div>
// <button
// id="toggleSidebarMobileSearch"
// type="button"
// className="rounded-lg p-2 text-gray-500 hover:bg-gray-100 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white lg:hidden"
// >
// <span className="sr-only">Search</span>
// <BsSearch
// className="h-6 w-6 text-gray-500 dark:text-gray-400"
// fill="currentColor"
// />
// </button>
// {/* {session && <NotificationsDropdownComponent session={session} />}
// {false && <AppsDropdownComponent />}
// <ThemeToggler />
// {session && <ProfileDropdown session={session} />} */}
// <NavbarLogin session={session} status={status} />
// </div>
// </div>
// </div>
// </nav>
);
};

View File

@@ -10,37 +10,33 @@ const testimonials = [
text: "Well.. since they discontinued Mr. Matey",
from: "Fergal Moran",
fromTitle: "World's most handsome man",
fromAvatar:
"https://flowbite.s3.amazonaws.com/blocks/marketing-ui/avatars/karen-nelson.png",
fromAvatar: "https://i.pravatar.cc/150?img=43",
},
{
headline: "Mmmmm.... human music",
text: "I like it",
from: "Ed Dunlea",
fromTitle: "Minister for moaning",
fromAvatar:
"https://flowbite.s3.amazonaws.com/blocks/marketing-ui/avatars/roberta-casas.png",
fromAvatar: "https://i.pravatar.cc/150?img=59",
},
{
headline: "Lovely hurling",
text: "Well, as lovely as hurling can be, which is to say not very.",
from: "Adam Dunbar",
fromTitle: "Hurler on the ditch",
fromAvatar:
"https://flowbite.s3.amazonaws.com/blocks/marketing-ui/avatars/jese-leos.png",
fromAvatar: "https://i.pravatar.cc/150?img=38",
},
{
headline: "D'ya have the balla?",
text: "You fucking do, g'wan and play it ya cunt!!",
from: "Gangrene McDandruff",
fromTitle: "Local crank",
fromAvatar:
"https://flowbite.s3.amazonaws.com/blocks/marketing-ui/avatars/joseph-mcfall.png",
fromAvatar: "https://i.pravatar.cc/150?img=10",
},
];
const HeroPage = () => {
return (
<div className="container mx-auto -mt-16 px-4 text-center lg:px-0 xl:px-32">
<div className="container mx-auto -mt-32 px-4 text-center lg:px-0 xl:px-32">
<h1 className="mb-3 text-3xl font-bold tracking-tight text-gray-900 dark:text-gray-200 sm:text-5xl sm:leading-none md:tracking-wide">
Welcome to MixyBoos
</h1>

View File

@@ -1,22 +1,10 @@
import { Dropdown } from "flowbite-react";
import * as React from "react";
const Datepicker: React.FC = () => {
return (
<span className="text-sm text-gray-600">
<Dropdown inline label="Last 7 days">
<Dropdown.Item>
<strong>Sep 16, 2021 - Sep 22, 2021</strong>
</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item>Yesterday</Dropdown.Item>
<Dropdown.Item>Today</Dropdown.Item>
<Dropdown.Item>Last 7 days</Dropdown.Item>
<Dropdown.Item>Last 30 days</Dropdown.Item>
<Dropdown.Item>Last 90 days</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item>Custom...</Dropdown.Item>
</Dropdown>
</span>
<div className="text-sm text-gray-600">
Pick a date, any date... OMG NO!!!! NOT THAT ONE!!
</div>
);
};
export default Datepicker;

View File

@@ -142,7 +142,7 @@ const PlayersComponent = () => {
<div className="flex min-w-0 items-center">
<img
className="h-10 w-10 flex-shrink-0"
src="https://flowbite-admin-dashboard.vercel.app/images/products/iphone.png"
src="https://placekeanu.com/200/150"
alt="imac image"
/>
<div className="ml-3">
@@ -178,7 +178,7 @@ const PlayersComponent = () => {
<div className="flex min-w-0 items-center">
<img
className="h-10 w-10 flex-shrink-0"
src="https://flowbite-admin-dashboard.vercel.app/images/products/imac.png"
src="https://placekeanu.com/200/150"
alt="imac image"
/>
<div className="ml-3">
@@ -214,7 +214,7 @@ const PlayersComponent = () => {
<div className="flex min-w-0 items-center">
<img
className="h-10 w-10 flex-shrink-0"
src="https://flowbite-admin-dashboard.vercel.app/images/products/watch.png"
src="https://placekeanu.com/200/150"
alt="watch image"
/>
<div className="ml-3">
@@ -250,7 +250,7 @@ const PlayersComponent = () => {
<div className="flex min-w-0 items-center">
<img
className="h-10 w-10 flex-shrink-0"
src="https://flowbite-admin-dashboard.vercel.app/images/products/ipad.png"
src="https://placekeanu.com/200/150"
alt="ipad image"
/>
<div className="ml-3">
@@ -286,7 +286,7 @@ const PlayersComponent = () => {
<div className="flex min-w-0 items-center">
<img
className="h-10 w-10 flex-shrink-0"
src="https://flowbite-admin-dashboard.vercel.app/images/products/imac.png"
src="https://placekeanu.com/200/150"
alt="imac image"
/>
<div className="ml-3">
@@ -334,7 +334,7 @@ const PlayersComponent = () => {
<div className="flex-shrink-0">
<img
className="h-8 w-8 rounded-full"
src="https://flowbite-admin-dashboard.vercel.app/images/users/neil-sims.png"
src="https://placekeanu.com/200/150"
alt="Neil image"
/>
</div>
@@ -343,7 +343,7 @@ const PlayersComponent = () => {
Neil Sims
</p>
<p className="truncate text-sm text-gray-500 dark:text-gray-400">
email@flowbite.com
email@mixyboos.com
</p>
</div>
<div className="inline-flex items-center text-base font-semibold text-gray-900 dark:text-white">
@@ -356,7 +356,7 @@ const PlayersComponent = () => {
<div className="flex-shrink-0">
<img
className="h-8 w-8 rounded-full"
src="https://flowbite-admin-dashboard.vercel.app/images/users/bonnie-green.png"
src="https://placekeanu.com/200/150"
alt="Neil image"
/>
</div>
@@ -365,7 +365,7 @@ const PlayersComponent = () => {
Bonnie Green
</p>
<p className="truncate text-sm text-gray-500 dark:text-gray-400">
email@flowbite.com
email@mixyboos.com
</p>
</div>
<div className="inline-flex items-center text-base font-semibold text-gray-900 dark:text-white">
@@ -378,7 +378,7 @@ const PlayersComponent = () => {
<div className="flex-shrink-0">
<img
className="h-8 w-8 rounded-full"
src="https://flowbite-admin-dashboard.vercel.app/images/users/michael-gough.png"
src="https://placekeanu.com/200/150"
alt="Neil image"
/>
</div>
@@ -387,7 +387,7 @@ const PlayersComponent = () => {
Michael Gough
</p>
<p className="truncate text-sm text-gray-500 dark:text-gray-400">
email@flowbite.com
email@miyboos.com
</p>
</div>
<div className="inline-flex items-center text-base font-semibold text-gray-900 dark:text-white">
@@ -400,7 +400,7 @@ const PlayersComponent = () => {
<div className="flex-shrink-0">
<img
className="h-8 w-8 rounded-full"
src="https://flowbite-admin-dashboard.vercel.app/images/users/thomas-lean.png"
src="https://placekeanu.com/200/150"
alt="Neil image"
/>
</div>
@@ -409,7 +409,7 @@ const PlayersComponent = () => {
Thomes Lean
</p>
<p className="truncate text-sm text-gray-500 dark:text-gray-400">
email@flowbite.com
email@mixyboos.com
</p>
</div>
<div className="inline-flex items-center text-base font-semibold text-gray-900 dark:text-white">
@@ -422,7 +422,7 @@ const PlayersComponent = () => {
<div className="flex-shrink-0">
<img
className="h-8 w-8 rounded-full"
src="https://flowbite-admin-dashboard.vercel.app/images/users/lana-byrd.png"
src="https://placekeanu.com/200/150"
alt="Neil image"
/>
</div>
@@ -431,7 +431,7 @@ const PlayersComponent = () => {
Lana Byrd
</p>
<p className="truncate text-sm text-gray-500 dark:text-gray-400">
email@flowbite.com
email@mixyboos.com
</p>
</div>
<div className="inline-flex items-center text-base font-semibold text-gray-900 dark:text-white">

View File

@@ -1,5 +1,4 @@
import React from "react";
import { Tooltip } from "flowbite-react";
import { CopyToClipboard } from "react-copy-to-clipboard";
import { HiOutlineDuplicate } from "react-icons/hi";

6
src/lib/utils/styles.ts Normal file
View File

@@ -0,0 +1,6 @@
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}

View File

@@ -1,3 +1,99 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 47.4% 11.2%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 47.4% 11.2%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--card: 0 0% 100%;
--card-foreground: 222.2 47.4% 11.2%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 100% 50%;
--destructive-foreground: 210 40% 98%;
--ring: 215 20.2% 65.1%;
--radius: 0.5rem;
}
.dark {
--background: 224 71% 4%;
--foreground: 213 31% 91%;
--muted: 223 47% 11%;
--muted-foreground: 215.4 16.3% 56.9%;
--accent: 216 34% 17%;
--accent-foreground: 210 40% 98%;
--popover: 224 71% 4%;
--popover-foreground: 215 20.2% 65.1%;
--border: 216 34% 17%;
--input: 216 34% 17%;
--card: 224 71% 4%;
--card-foreground: 213 31% 91%;
--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 1.2%;
--secondary: 222.2 47.4% 11.2%;
--secondary-foreground: 210 40% 98%;
--destructive: 0 63% 31%;
--destructive-foreground: 210 40% 98%;
--ring: 216 34% 17%;
--radius: 0.5rem;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
font-feature-settings: "rlig" 1, "calt" 1;
}
}
@layer utilities {
.step {
counter-increment: step;
}
.step:before {
@apply absolute inline-flex h-8 w-8 items-center justify-center rounded-full bg-muted text-center -indent-px text-base font-medium;
@apply ml-[-41px];
content: counter(step);
}
}
@media (max-width: 640px) {
.container {
@apply px-4;
}
}

View File

@@ -1,9 +1,77 @@
import { type Config } from "tailwindcss";
import { fontFamily } from "tailwindcss/defaultTheme";
export default {
darkMode: ["class"],
content: ["./src/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {},
container: {
center: true,
padding: "2rem",
screens: {
"2xl": "1400px",
},
plugins: [],
},
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
secondary: {
DEFAULT: "hsl(var(--secondary))",
foreground: "hsl(var(--secondary-foreground))",
},
destructive: {
DEFAULT: "hsl(var(--destructive))",
foreground: "hsl(var(--destructive-foreground))",
},
muted: {
DEFAULT: "hsl(var(--muted))",
foreground: "hsl(var(--muted-foreground))",
},
accent: {
DEFAULT: "hsl(var(--accent))",
foreground: "hsl(var(--accent-foreground))",
},
popover: {
DEFAULT: "hsl(var(--popover))",
foreground: "hsl(var(--popover-foreground))",
},
card: {
DEFAULT: "hsl(var(--card))",
foreground: "hsl(var(--card-foreground))",
},
},
borderRadius: {
lg: `var(--radius)`,
md: `calc(var(--radius) - 2px)`,
sm: "calc(var(--radius) - 4px)",
},
fontFamily: {
sans: ["var(--font-sans)", ...fontFamily.sans],
},
keyframes: {
"accordion-down": {
from: { height: "0" },
to: { height: "var(--radix-accordion-content-height)" },
},
"accordion-up": {
from: { height: "var(--radix-accordion-content-height)" },
to: { height: "0" },
},
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
},
},
},
plugins: [require("tailwindcss-animate")],
} satisfies Config;