Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,22 @@ jobs:

- name: Build
run: bun run build

quality:
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Setup Biome
uses: biomejs/setup-biome@v2
with:
version: latest

- name: Run Biome
run: biome ci .
40 changes: 40 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"$schema": "https://biomejs.dev/schemas/2.2.6/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"files": {
"ignoreUnknown": true,
"includes": ["**", "!node_modules", "!.next", "!dist", "!build"]
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"a11y": {
"noSvgWithoutTitle": "off"
},
"suspicious": {
"noUnknownAtRules": "off"
}
},
"domains": {
"next": "recommended",
"react": "recommended"
}
},
"assist": {
"actions": {
"source": {
"organizeImports": "on"
}
}
}
}
845 changes: 144 additions & 701 deletions bun.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion components.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}
}
16 changes: 0 additions & 16 deletions eslint.config.mjs

This file was deleted.

59 changes: 30 additions & 29 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,51 @@
"private": true,
"scripts": {
"dev": "next dev --turbopack",
"build": "next build",
"build": "next build --turbopack",
"start": "next start",
"lint": "next lint",
"lint": "biome check",
"format": "biome format --write",
"format-and-lint:fix": "biome check --write",
"ui:add": "bunx --bun shadcn@latest add"
},
"dependencies": {
"@hookform/resolvers": "^5.1.1",
"@hookform/resolvers": "^5.2.2",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-dialog": "^1.1.14",
"@radix-ui/react-dropdown-menu": "^2.1.15",
"@radix-ui/react-hover-card": "^1.1.14",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-hover-card": "^1.1.15",
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-popover": "^1.1.14",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-switch": "^1.2.5",
"@radix-ui/react-tabs": "^1.1.12",
"@radix-ui/react-tooltip": "^1.2.7",
"@radix-ui/react-switch": "^1.2.6",
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-tooltip": "^1.2.8",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"geist": "^1.3.1",
"lucide-react": "^0.515.0",
"next": "15.3.3",
"geist": "^1.5.1",
"lucide-react": "^0.546.0",
"next": "15.5.6",
"next-themes": "^0.4.6",
"nextjs-toploader": "^3.8.16",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-hook-form": "^7.57.0",
"sonner": "^2.0.5",
"nextjs-toploader": "^3.9.17",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-hook-form": "^7.65.0",
"sonner": "^2.0.7",
"tailwind-merge": "^3.3.1",
"tailwindcss-animate": "^1.0.7",
"vaul": "^1.1.2",
"zod": "^3.25.64"
"zod": "^4.1.12"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.1.10",
"@types/node": "^20.17.16",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"eslint": "^9.28.0",
"eslint-config-next": "15.3.3",
"postcss": "^8.5.1",
"tailwindcss": "^4.1.10",
"tw-animate-css": "^1.3.4",
"typescript": "^5.7.3"
"@biomejs/biome": "2.2.6",
"@tailwindcss/postcss": "^4.1.14",
"@types/node": "22",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.2",
"postcss": "^8.5.6",
"tailwindcss": "^4.1.14",
"tw-animate-css": "^1.4.0",
"typescript": "^5.9.3"
}
}
2 changes: 1 addition & 1 deletion postcss.config.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
'@tailwindcss/postcss': {},
"@tailwindcss/postcss": {},
},
};

Expand Down
6 changes: 3 additions & 3 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { Metadata } from "next";
import { GeistSans } from "geist/font/sans";
import { GeistMono } from "geist/font/mono";
import { GeistSans } from "geist/font/sans";
import type { Metadata } from "next";
import NextTopLoader from "nextjs-toploader";

import Navbar from "@/components/navbar";
import { Toaster } from "@/components/ui/sonner";
import { ThemeProvider } from "@/components/theme-provider";
import { Toaster } from "@/components/ui/sonner";

import "./globals.css";

Expand Down
2 changes: 1 addition & 1 deletion src/app/robots.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MetadataRoute } from "next";
import type { MetadataRoute } from "next";

export default function robots(): MetadataRoute.Robots {
return {
Expand Down
4 changes: 3 additions & 1 deletion src/app/user/[username]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import Footer from "@/components/footer";
import { Preview } from "@/components/preview";

export default async function Home(props: { params: Promise<{ username: string }> }) {
export default async function Home(props: {
params: Promise<{ username: string }>;
}) {
const params = await props.params;
return (
<main className="container flex flex-col justify-between min-h-screen pt-36">
Expand Down
20 changes: 7 additions & 13 deletions src/components/footer.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card";

import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Button } from "./ui/button";

export default function Footer() {
return (
<footer className="w-full font-mono py-3">
<HoverCard>
<HoverCardTrigger asChild>
<p className="text-center text-muted-foreground sm:text-sm text-xs">
&copy; 2025{" "}
<a
href="https://github.com/omsimos"
target="_blank"
rel="noopener noreferrer"
>
OMSIMOS
</a>{" "}
· MIT License
</p>
<button
type="button"
className="w-full text-center text-muted-foreground sm:text-sm text-xs bg-transparent hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-muted-foreground/40 rounded-md py-1"
>
&copy; 2025 <span className="underline">OMSIMOS</span> · MIT License
</button>
</HoverCardTrigger>
<HoverCardContent sideOffset={25} className="w-full max-w-96 mr-5">
<div className="flex justify-between space-x-4">
Expand Down
70 changes: 33 additions & 37 deletions src/components/gh-stats-form.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,47 @@
"use client";

import { z } from "zod";
import { toast } from "sonner";
import { cn } from "@/lib/utils";
import themes from "@/themes.json";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Check, ChevronsUpDown } from "lucide-react";
import { useRouter, useSearchParams } from "next/navigation";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import { Button } from "@/components/ui/button";

import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "@/components/ui/command";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";

import { Input } from "@/components/ui/input";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";

import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "@/components/ui/command";

import { Switch } from "@/components/ui/switch";
import { cn } from "@/lib/utils";
import themes from "@/themes.json";
import { Icons } from "./icons";
import { Label } from "./ui/label";
import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import { Button } from "@/components/ui/button";
import { Check, ChevronsUpDown } from "lucide-react";
import { useRouter, useSearchParams } from "next/navigation";
import { useState } from "react";

const FormSchema = z.object({
username: z.string().min(2, {
message: "Username must be at least 2 characters.",
}),
theme: z.string({
required_error: "Please select a theme.",
}),
username: z
.string()
.min(2, { message: "Username must be at least 2 characters." }),
theme: z.string().min(1, { message: "Please select a theme." }),
hideBorder: z.boolean(),
countPrivate: z.boolean(),
});
Expand Down Expand Up @@ -75,7 +71,7 @@ export function GhStatsForm() {
toast.success("Generated GitHub Stats!");

push(
`/user/${username}?theme=${theme}&hide_border=${hideBorder}&count_private=${countPrivate}`
`/user/${username}?theme=${theme}&hide_border=${hideBorder}&count_private=${countPrivate}`,
);
}

Expand All @@ -98,7 +94,7 @@ export function GhStatsForm() {
<FormControl>
<Input placeholder="omsimos" {...field} />
</FormControl>
{/* <FormMessage /> */}
<FormMessage className="sr-only" />
</FormItem>
)}
/>
Expand All @@ -118,7 +114,7 @@ export function GhStatsForm() {
"w-full justify-between",
!field.value || field.value === "default"
? "text-muted-foreground"
: ""
: "",
)}
>
{field.value
Expand Down Expand Up @@ -149,7 +145,7 @@ export function GhStatsForm() {
"mr-2 h-4 w-4",
theme.value === field.value
? "opacity-100"
: "opacity-0"
: "opacity-0",
)}
/>
{theme.label}
Expand All @@ -160,7 +156,7 @@ export function GhStatsForm() {
</Command>
</PopoverContent>
</Popover>
{/* <FormMessage /> */}
<FormMessage className="sr-only" />
</FormItem>
)}
/>
Expand All @@ -186,11 +182,11 @@ export function GhStatsForm() {
<Switch
checked={field.value}
onCheckedChange={field.onChange}
id="privCommits"
id="hide-border-toggle"
/>
</FormControl>
</FormItem>
<Label htmlFor="priv-commits" className="mb-1">
<Label htmlFor="hide-border-toggle" className="mb-1">
Hide Card Border
</Label>
</div>
Expand All @@ -207,11 +203,11 @@ export function GhStatsForm() {
<Switch
checked={field.value}
onCheckedChange={field.onChange}
id="privCommits"
id="count-private-toggle"
/>
</FormControl>
</FormItem>
<Label htmlFor="priv-commits" className="mb-1">
<Label htmlFor="count-private-toggle" className="mb-1">
Count Private Commits
</Label>
</div>
Expand Down
Loading