Skip to content

Commit

Permalink
Create layout for application
Browse files Browse the repository at this point in the history
  • Loading branch information
yoshikouki committed Sep 19, 2024
1 parent 84098f5 commit 223341d
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 16 deletions.
2 changes: 1 addition & 1 deletion bin/generate-logo.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// biome-ignore lint/style/useNodejsImportProtocol: <explanation>
import { parseArgs } from "util";
import { renderLogoSVG } from "./logo";
import sharp from "sharp";
import { renderLogoSVG } from "./logo";

const DEFAULT_CONFIG = {
DEFAULT_INPUT: "./public/logo.webp",
Expand Down
23 changes: 8 additions & 15 deletions src/app/app-header.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
import { AnimatedLink } from "@/components/animated-link";
import { NavIconButton } from "@/components/ui/nav-icon-button";
import { url } from "@/lib/url";
import { ThemeToggle } from "./theme-toggle";
import { LogoIcon } from "./logo";

export const AppHeader = () => {
return (
<header className="flex w-full flex-col items-center justify-center">
<div className="flex w-full max-w-xl items-center justify-between p-4">
<AnimatedLink
href={url.root}
className="flex items-center justify-center gap-2"
>
<img
src={"/logo-no-padding.webp"}
loading="eager"
alt="service logo"
width={32}
/>
<h1 className="font-black text-6xl">Lastio</h1>
<header className="fixed inset-x-0 top-0 z-50 flex items-center justify-between">
<div className="flex w-full max-w-xl items-center justify-between p-2">
<AnimatedLink href={url.root}>
<NavIconButton>
<LogoIcon className="size-6 stroke-foreground" />
</NavIconButton>
</AnimatedLink>
<ThemeToggle />
</div>
</header>
);
Expand Down
17 changes: 17 additions & 0 deletions src/app/app-nav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { NavIconButton } from "@/components/ui/nav-icon-button";
import { HomeIcon, SettingsIcon } from "lucide-react";

export const AppNav = () => {
return (
<nav className="fixed inset-x-0 bottom-0 z-50 flex items-center justify-between p-2">
<div className="flex gap-2">
<NavIconButton>
<HomeIcon className="size-6 stroke-foreground" />
</NavIconButton>
</div>
<NavIconButton>
<SettingsIcon className="size-6 stroke-foreground" strokeWidth={1.5} />
</NavIconButton>
</nav>
);
};
20 changes: 20 additions & 0 deletions src/app/logo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export const LogoIcon = ({ className }: { className?: string }) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className={className}
>
<title>Lastio</title>
<circle cx="12" cy="12" r="10" />
<polyline points="15 6.8 12 12 8 10" />
</svg>
);
};
2 changes: 2 additions & 0 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { getActivitiesByGroup } from "@/repositories/activity";
import { ActivityItem } from "./activity-item";
import { AppHeader } from "./app-header";
import { AppNav } from "./app-nav";

export default async function HomePage() {
const activities = await getActivitiesByGroup("group-1");

return (
<>
<AppHeader />
<AppNav />
<main className="flex flex-col items-center justify-center gap-10 py-10">
<div className="flex flex-col">
{activities.map((activity) => (
Expand Down
57 changes: 57 additions & 0 deletions src/components/ui/nav-icon-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Slot } from "@radix-ui/react-slot";
import { type VariantProps, cva } from "class-variance-authority";
import * as React from "react";

import { cn } from "@/lib/utils";

const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default:
"text-primary-foreground hover:bg-primary/90 rounded-lg bg-border/75 p-3 backdrop-blur",
destructive:
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border border-input bg-background 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: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "p-3",
},
},
defaultVariants: {
variant: "default",
size: "icon",
},
},
);

export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
}

const NavIconButton = 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}
/>
);
},
);
NavIconButton.displayName = "NavIconButton";

export { NavIconButton, buttonVariants };

0 comments on commit 223341d

Please sign in to comment.