Function bodies 164 total
HomePage function · typescript · L19-L250 (232 LOC)src/app/(marketing)/page.tsx
export default function HomePage() {
return (
<>
{/* Hero */}
<section className="relative overflow-hidden px-4 py-24 sm:py-32">
<div className="mx-auto max-w-4xl text-center">
<Badge variant="secondary" className="mb-4">
<Sparkles className="mr-1 h-3 w-3" /> AI-Powered Business Tools
</Badge>
<h1 className="text-4xl font-bold tracking-tight sm:text-6xl">
Run Your Business{" "}
<span className="text-primary">Smarter</span>, Not Harder
</h1>
<p className="mt-6 text-lg text-muted-foreground sm:text-xl">
Review management, social media content, and short-form video
scripting — all powered by AI. Built for local business owners who
want to grow without the grind.
</p>
<div className="mt-8 flex flex-col items-center justify-center gap-4 sm:flex-row">
<Link href="/signup">
<Button size="lg" className=NotFound function · typescript · L4-L17 (14 LOC)src/app/not-found.tsx
export default function NotFound() {
return (
<div className="flex min-h-screen flex-col items-center justify-center text-center px-4">
<h1 className="text-6xl font-bold text-primary">404</h1>
<p className="mt-4 text-xl font-semibold">Page not found</p>
<p className="mt-2 text-muted-foreground">
The page you're looking for doesn't exist or has been moved.
</p>
<Link href="/" className="mt-6">
<Button>Go Home</Button>
</Link>
</div>
);
}AdminSidebar function · typescript · L25-L84 (60 LOC)src/components/admin/admin-sidebar.tsx
export function AdminSidebar({ className }: { className?: string }) {
const pathname = usePathname();
const router = useRouter();
const supabase = createClient();
async function handleLogout() {
await supabase.auth.signOut();
toast.success("Logged out");
router.push("/login");
router.refresh();
}
return (
<aside className={cn("flex h-full w-64 flex-col border-r bg-card", className)}>
<div className="flex h-16 items-center gap-2 border-b px-6">
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-destructive text-destructive-foreground font-bold">
A
</div>
<span className="text-lg font-bold">Admin</span>
</div>
<nav className="flex-1 space-y-1 p-3">
{links.map((link) => {
const isActive =
pathname === link.href ||
(link.href !== "/admin" && pathname.startsWith(link.href));
return (
<Link key={link.href} href={link.href}>
handleLogout function · typescript · L30-L35 (6 LOC)src/components/admin/admin-sidebar.tsx
async function handleLogout() {
await supabase.auth.signOut();
toast.success("Logged out");
router.push("/login");
router.refresh();
}UsersTable function · typescript · L37-L257 (221 LOC)src/components/admin/users-table.tsx
export function UsersTable({ users }: { users: User[] }) {
const [search, setSearch] = useState("");
const [planFilter, setPlanFilter] = useState("all");
const [actionLoading, setActionLoading] = useState<string | null>(null);
const router = useRouter();
const filtered = users.filter((u) => {
if (
search &&
!u.email.toLowerCase().includes(search.toLowerCase()) &&
!(u.full_name ?? "").toLowerCase().includes(search.toLowerCase())
)
return false;
if (planFilter !== "all" && u.plan_id !== planFilter) return false;
return true;
});
async function changePlan(userId: string, newPlan: PlanId) {
setActionLoading(userId);
const res = await fetch("/api/admin/users", {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ userId, action: "change_plan", plan_id: newPlan }),
});
const data = await res.json();
if (!res.ok) {
toast.error(data.error || "Failed to changechangePlan function · typescript · L54-L69 (16 LOC)src/components/admin/users-table.tsx
async function changePlan(userId: string, newPlan: PlanId) {
setActionLoading(userId);
const res = await fetch("/api/admin/users", {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ userId, action: "change_plan", plan_id: newPlan }),
});
const data = await res.json();
if (!res.ok) {
toast.error(data.error || "Failed to change plan");
} else {
toast.success(`Plan changed to ${newPlan}`);
router.refresh();
}
setActionLoading(null);
}toggleBan function · typescript · L71-L89 (19 LOC)src/components/admin/users-table.tsx
async function toggleBan(userId: string, currentlyBanned: boolean) {
setActionLoading(userId);
const res = await fetch("/api/admin/users", {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
userId,
action: currentlyBanned ? "unban" : "ban",
}),
});
const data = await res.json();
if (!res.ok) {
toast.error(data.error || "Failed");
} else {
toast.success(currentlyBanned ? "User unbanned" : "User banned");
router.refresh();
}
setActionLoading(null);
}All rows scored by the Repobility analyzer (https://repobility.com)
BusinessSwitcher function · typescript · L23-L70 (48 LOC)src/components/dashboard/business-switcher.tsx
export function BusinessSwitcher() {
const [businesses, setBusinesses] = useState<Business[]>([]);
const { currentBusiness, setCurrentBusiness } = useBusinessStore();
const supabase = createClient();
useEffect(() => {
async function loadBusinesses() {
const { data } = await supabase
.from("businesses")
.select("*")
.order("created_at");
if (data && data.length > 0) {
setBusinesses(data);
if (!currentBusiness) {
setCurrentBusiness(data[0]);
}
}
}
loadBusinesses();
}, []); // eslint-disable-line react-hooks/exhaustive-deps
if (businesses.length === 0) return null;
return (
<Select
value={currentBusiness?.id || ""}
onValueChange={(id) => {
const biz = businesses.find((b) => b.id === id);
if (biz) setCurrentBusiness(biz);
}}
>
<SelectTrigger className="w-[200px]">
<div className="flex items-center gap-2">
<Building2 clasloadBusinesses function · typescript · L29-L41 (13 LOC)src/components/dashboard/business-switcher.tsx
async function loadBusinesses() {
const { data } = await supabase
.from("businesses")
.select("*")
.order("created_at");
if (data && data.length > 0) {
setBusinesses(data);
if (!currentBusiness) {
setCurrentBusiness(data[0]);
}
}
}DashboardSidebar function · typescript · L30-L88 (59 LOC)src/components/dashboard/sidebar.tsx
export function DashboardSidebar({ className }: { className?: string }) {
const pathname = usePathname();
const router = useRouter();
const supabase = createClient();
async function handleLogout() {
await supabase.auth.signOut();
toast.success("Logged out");
router.push("/login");
router.refresh();
}
return (
<aside
className={cn(
"flex h-full w-64 flex-col border-r bg-card",
className
)}
>
<div className="flex h-16 items-center gap-2 border-b px-6">
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary text-primary-foreground font-bold">
B
</div>
<span className="text-lg font-bold">BossBoard</span>
</div>
<nav className="flex-1 space-y-1 p-3">
{links.map((link) => {
const isActive =
pathname === link.href ||
(link.href !== "/dashboard" && pathname.startsWith(link.href));
return (
<handleLogout function · typescript · L35-L40 (6 LOC)src/components/dashboard/sidebar.tsx
async function handleLogout() {
await supabase.auth.signOut();
toast.success("Logged out");
router.push("/login");
router.refresh();
}DashboardTopbar function · typescript · L15-L36 (22 LOC)src/components/dashboard/topbar.tsx
export function DashboardTopbar() {
return (
<header className="flex h-16 items-center justify-between border-b bg-card px-4 lg:px-6">
<div className="flex items-center gap-3">
<Sheet>
<SheetTrigger asChild>
<Button variant="ghost" size="icon" className="lg:hidden">
<Menu className="h-5 w-5" />
<span className="sr-only">Toggle menu</span>
</Button>
</SheetTrigger>
<SheetContent side="left" className="w-64 p-0">
<SheetTitle className="sr-only">Navigation</SheetTitle>
<DashboardSidebar />
</SheetContent>
</Sheet>
<BusinessSwitcher />
</div>
<ThemeToggle />
</header>
);
}UsageChart function · typescript · L12-L44 (33 LOC)src/components/dashboard/usage-chart.tsx
export function UsageChart({
data,
}: {
data: { date: string; credits: number }[];
}) {
return (
<div className="h-[250px] w-full">
<ResponsiveContainer width="100%" height="100%">
<BarChart data={data}>
<XAxis
dataKey="date"
fontSize={12}
tickLine={false}
axisLine={false}
/>
<YAxis fontSize={12} tickLine={false} axisLine={false} />
<Tooltip
contentStyle={{
backgroundColor: "hsl(var(--card))",
border: "1px solid hsl(var(--border))",
borderRadius: "8px",
}}
/>
<Bar
dataKey="credits"
fill="hsl(var(--primary))"
radius={[4, 4, 0, 0]}
/>
</BarChart>
</ResponsiveContainer>
</div>
);
}MarketingFooter function · typescript · L3-L49 (47 LOC)src/components/marketing/footer.tsx
export function MarketingFooter() {
return (
<footer className="border-t bg-muted/30">
<div className="mx-auto max-w-7xl px-4 py-12 sm:px-6 lg:px-8">
<div className="grid grid-cols-2 gap-8 md:grid-cols-4">
<div>
<div className="flex items-center gap-2 mb-4">
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary text-primary-foreground font-bold">
B
</div>
<span className="text-lg font-bold">BossBoard</span>
</div>
<p className="text-sm text-muted-foreground">
AI-powered tools for local business owners.
</p>
</div>
<div>
<h3 className="mb-3 text-sm font-semibold">Product</h3>
<ul className="space-y-2 text-sm text-muted-foreground">
<li><Link href="#features" className="hover:text-foreground">Features</Link></li>
<li><Link href="#pricing" classNMarketingNavbar function · typescript · L5-L49 (45 LOC)src/components/marketing/navbar.tsx
export function MarketingNavbar() {
return (
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
<div className="mx-auto flex h-16 max-w-7xl items-center justify-between px-4 sm:px-6 lg:px-8">
<Link href="/" className="flex items-center gap-2">
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary text-primary-foreground font-bold">
B
</div>
<span className="text-xl font-bold">BossBoard</span>
</Link>
<nav className="hidden items-center gap-6 md:flex">
<Link
href="#features"
className="text-sm text-muted-foreground hover:text-foreground transition-colors"
>
Features
</Link>
<Link
href="#pricing"
className="text-sm text-muted-foreground hover:text-foreground transition-colors"
>
Pricing
Provenance: Repobility (https://repobility.com) — every score reproducible from /scan/
PricingToggle function · typescript · L15-L78 (64 LOC)src/components/marketing/pricing-toggle.tsx
export function PricingToggle() {
const [annual, setAnnual] = useState(false);
return (
<div>
<div className="mb-8 flex items-center justify-center gap-3">
<Label htmlFor="billing" className="text-sm">Monthly</Label>
<Switch id="billing" checked={annual} onCheckedChange={setAnnual} />
<Label htmlFor="billing" className="text-sm">
Annual <Badge variant="secondary" className="ml-1">Save 17%</Badge>
</Label>
</div>
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-4">
{planOrder.map((planId) => {
const plan = plans[planId];
const price = annual ? plan.annualPrice : plan.monthlyPrice;
const isPro = planId === "pro";
return (
<Card key={planId} className={isPro ? "border-primary shadow-lg relative" : "relative"}>
{isPro && (
<div className="absolute -top-3 left-1/2 -translate-x-1/2">
<Badge className="bg-primarAddReviewDialog function · typescript · L27-L135 (109 LOC)src/components/reviews/add-review-dialog.tsx
export function AddReviewDialog({ businessId }: { businessId: string }) {
const [open, setOpen] = useState(false);
const [reviewerName, setReviewerName] = useState("");
const [rating, setRating] = useState("5");
const [reviewText, setReviewText] = useState("");
const [sentiment, setSentiment] = useState("positive");
const [loading, setLoading] = useState(false);
const router = useRouter();
const supabase = createClient();
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
setLoading(true);
const { error } = await supabase.from("reviews").insert({
business_id: businessId,
reviewer_name: reviewerName,
rating: parseInt(rating),
review_text: reviewText,
sentiment,
});
if (error) {
toast.error(error.message);
setLoading(false);
return;
}
toast.success("Review added!");
setOpen(false);
setReviewerName("");
setRating("5");
setReviewText("");
setSentiment("pohandleSubmit function · typescript · L37-L63 (27 LOC)src/components/reviews/add-review-dialog.tsx
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
setLoading(true);
const { error } = await supabase.from("reviews").insert({
business_id: businessId,
reviewer_name: reviewerName,
rating: parseInt(rating),
review_text: reviewText,
sentiment,
});
if (error) {
toast.error(error.message);
setLoading(false);
return;
}
toast.success("Review added!");
setOpen(false);
setReviewerName("");
setRating("5");
setReviewText("");
setSentiment("positive");
setLoading(false);
router.refresh();
}ReviewCard function · typescript · L20-L121 (102 LOC)src/components/reviews/review-card.tsx
export function ReviewCard({
review,
businessId,
}: {
review: Review;
businessId: string;
}) {
const [showReply, setShowReply] = useState(false);
const [generatedReply, setGeneratedReply] = useState("");
const [copied, setCopied] = useState(false);
const sentimentColor = {
positive: "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200",
neutral: "bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200",
negative: "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200",
};
async function copyToClipboard() {
await navigator.clipboard.writeText(generatedReply);
setCopied(true);
toast.success("Copied to clipboard!");
setTimeout(() => setCopied(false), 2000);
}
return (
<Card>
<CardContent className="pt-6">
<div className="flex items-start justify-between">
<div className="flex items-center gap-3">
<div className="flex h-10 w-10 items-center justify-center rounded-fcopyToClipboard function · typescript · L37-L42 (6 LOC)src/components/reviews/review-card.tsx
async function copyToClipboard() {
await navigator.clipboard.writeText(generatedReply);
setCopied(true);
toast.success("Copied to clipboard!");
setTimeout(() => setCopied(false), 2000);
}ReviewsList function · typescript · L23-L91 (69 LOC)src/components/reviews/reviews-list.tsx
export function ReviewsList({
reviews,
businessId,
}: {
reviews: Review[];
businessId: string;
}) {
const [filterRating, setFilterRating] = useState("all");
const [filterSentiment, setFilterSentiment] = useState("all");
const filtered = reviews.filter((r) => {
if (filterRating !== "all" && r.rating !== parseInt(filterRating))
return false;
if (filterSentiment !== "all" && r.sentiment !== filterSentiment)
return false;
return true;
});
return (
<div className="space-y-4">
<div className="flex flex-wrap items-center justify-between gap-3">
<div className="flex gap-3">
<Select value={filterRating} onValueChange={setFilterRating}>
<SelectTrigger className="w-[130px]">
<SelectValue placeholder="Rating" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all">All ratings</SelectItem>
{[5, 4, 3, 2, 1].map((r) => (
<SelectItem ScriptsFilter function · typescript · L39-L133 (95 LOC)src/components/scripts/scripts-filter.tsx
export function ScriptsFilter({ scripts }: { scripts: Script[] }) {
const [formatFilter, setFormatFilter] = useState("all");
const [searchQuery, setSearchQuery] = useState("");
const router = useRouter();
const supabase = createClient();
const filtered = scripts.filter((s) => {
if (formatFilter !== "all" && s.format !== formatFilter) return false;
if (
searchQuery &&
!s.title.toLowerCase().includes(searchQuery.toLowerCase()) &&
!s.topic.toLowerCase().includes(searchQuery.toLowerCase())
)
return false;
return true;
});
async function handleDelete(id: string) {
const { error } = await supabase.from("scripts").delete().eq("id", id);
if (error) {
toast.error(error.message);
return;
}
toast.success("Script deleted");
router.refresh();
}
return (
<div className="space-y-4">
<div className="flex gap-3">
<div className="relative flex-1">
<Search className="absolute left-3 tohandleDelete function · typescript · L56-L64 (9 LOC)src/components/scripts/scripts-filter.tsx
async function handleDelete(id: string) {
const { error } = await supabase.from("scripts").delete().eq("id", id);
if (error) {
toast.error(error.message);
return;
}
toast.success("Script deleted");
router.refresh();
}Repobility's GitHub App fixes findings like these · https://github.com/apps/repobility-bot
PaddleProvider function · typescript · L8-L26 (19 LOC)src/components/shared/paddle-provider.tsx
export function PaddleProvider({ children }: { children: React.ReactNode }) {
useEffect(() => {
if (paddleInitialized) return;
paddleInitialized = true;
const token = process.env.NEXT_PUBLIC_PADDLE_CLIENT_TOKEN;
if (!token) return;
initializePaddle({
token,
environment:
process.env.NEXT_PUBLIC_PADDLE_ENV === "production"
? "production"
: "sandbox",
});
}, []);
return <>{children}</>;
}ThemeProvider function · typescript · L6-L12 (7 LOC)src/components/shared/theme-provider.tsx
export function ThemeProvider({ children }: { children: ReactNode }) {
return (
<NextThemesProvider attribute="class" defaultTheme="system" enableSystem disableTransitionOnChange>
{children}
</NextThemesProvider>
);
}ThemeToggle function · typescript · L7-L21 (15 LOC)src/components/shared/theme-toggle.tsx
export function ThemeToggle() {
const { setTheme, theme } = useTheme();
return (
<Button
variant="ghost"
size="icon"
onClick={() => setTheme(theme === "light" ? "dark" : "light")}
>
<Sun className="h-5 w-5 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-5 w-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
);
}SocialPostsFilter function · typescript · L30-L131 (102 LOC)src/components/social/social-posts-filter.tsx
export function SocialPostsFilter({ posts }: { posts: SocialPost[] }) {
const [statusFilter, setStatusFilter] = useState("all");
const router = useRouter();
const supabase = createClient();
const filtered = posts.filter((p) => {
if (statusFilter !== "all" && p.status !== statusFilter) return false;
return true;
});
const statusColors: Record<string, string> = {
draft: "bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-200",
scheduled:
"bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200",
posted:
"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200",
};
async function handleDelete(id: string) {
const { error } = await supabase.from("social_posts").delete().eq("id", id);
if (error) {
toast.error(error.message);
return;
}
toast.success("Post deleted");
router.refresh();
}
return (
<div className="space-y-4">
<Select value={statusFilter} onValueChange={setStatuhandleDelete function · typescript · L48-L56 (9 LOC)src/components/social/social-posts-filter.tsx
async function handleDelete(id: string) {
const { error } = await supabase.from("social_posts").delete().eq("id", id);
if (error) {
toast.error(error.message);
return;
}
toast.success("Post deleted");
router.refresh();
}Avatar function · typescript · L8-L26 (19 LOC)src/components/ui/avatar.tsx
function Avatar({
className,
size = "default",
...props
}: React.ComponentProps<typeof AvatarPrimitive.Root> & {
size?: "default" | "sm" | "lg"
}) {
return (
<AvatarPrimitive.Root
data-slot="avatar"
data-size={size}
className={cn(
"group/avatar relative flex size-8 shrink-0 overflow-hidden rounded-full select-none data-[size=lg]:size-10 data-[size=sm]:size-6",
className
)}
{...props}
/>
)
}AvatarImage function · typescript · L28-L39 (12 LOC)src/components/ui/avatar.tsx
function AvatarImage({
className,
...props
}: React.ComponentProps<typeof AvatarPrimitive.Image>) {
return (
<AvatarPrimitive.Image
data-slot="avatar-image"
className={cn("aspect-square size-full", className)}
{...props}
/>
)
}AvatarFallback function · typescript · L41-L55 (15 LOC)src/components/ui/avatar.tsx
function AvatarFallback({
className,
...props
}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
return (
<AvatarPrimitive.Fallback
data-slot="avatar-fallback"
className={cn(
"bg-muted text-muted-foreground flex size-full items-center justify-center rounded-full text-sm group-data-[size=sm]/avatar:text-xs",
className
)}
{...props}
/>
)
}Repobility analyzer · published findings · https://repobility.com
AvatarBadge function · typescript · L57-L71 (15 LOC)src/components/ui/avatar.tsx
function AvatarBadge({ className, ...props }: React.ComponentProps<"span">) {
return (
<span
data-slot="avatar-badge"
className={cn(
"bg-primary text-primary-foreground ring-background absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full ring-2 select-none",
"group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden",
"group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2",
"group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2",
className
)}
{...props}
/>
)
}AvatarGroup function · typescript · L73-L84 (12 LOC)src/components/ui/avatar.tsx
function AvatarGroup({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="avatar-group"
className={cn(
"*:data-[slot=avatar]:ring-background group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2",
className
)}
{...props}
/>
)
}AvatarGroupCount function · typescript · L86-L100 (15 LOC)src/components/ui/avatar.tsx
function AvatarGroupCount({
className,
...props
}: React.ComponentProps<"div">) {
return (
<div
data-slot="avatar-group-count"
className={cn(
"bg-muted text-muted-foreground ring-background relative flex size-8 shrink-0 items-center justify-center rounded-full text-sm ring-2 group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3",
className
)}
{...props}
/>
)
}Badge function · typescript · L29-L46 (18 LOC)src/components/ui/badge.tsx
function Badge({
className,
variant = "default",
asChild = false,
...props
}: React.ComponentProps<"span"> &
VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
const Comp = asChild ? Slot.Root : "span"
return (
<Comp
data-slot="badge"
data-variant={variant}
className={cn(badgeVariants({ variant }), className)}
{...props}
/>
)
}Button function · typescript · L41-L62 (22 LOC)src/components/ui/button.tsx
function Button({
className,
variant = "default",
size = "default",
asChild = false,
...props
}: React.ComponentProps<"button"> &
VariantProps<typeof buttonVariants> & {
asChild?: boolean
}) {
const Comp = asChild ? Slot.Root : "button"
return (
<Comp
data-slot="button"
data-variant={variant}
data-size={size}
className={cn(buttonVariants({ variant, size, className }))}
{...props}
/>
)
}Card function · typescript · L5-L16 (12 LOC)src/components/ui/card.tsx
function Card({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card"
className={cn(
"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
className
)}
{...props}
/>
)
}CardHeader function · typescript · L18-L29 (12 LOC)src/components/ui/card.tsx
function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-header"
className={cn(
"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
className
)}
{...props}
/>
)
}CardTitle function · typescript · L31-L39 (9 LOC)src/components/ui/card.tsx
function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-title"
className={cn("leading-none font-semibold", className)}
{...props}
/>
)
}All rows scored by the Repobility analyzer (https://repobility.com)
CardDescription function · typescript · L41-L49 (9 LOC)src/components/ui/card.tsx
function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-description"
className={cn("text-muted-foreground text-sm", className)}
{...props}
/>
)
}CardAction function · typescript · L51-L62 (12 LOC)src/components/ui/card.tsx
function CardAction({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-action"
className={cn(
"col-start-2 row-span-2 row-start-1 self-start justify-self-end",
className
)}
{...props}
/>
)
}CardContent function · typescript · L64-L72 (9 LOC)src/components/ui/card.tsx
function CardContent({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-content"
className={cn("px-6", className)}
{...props}
/>
)
}CardFooter function · typescript · L74-L82 (9 LOC)src/components/ui/card.tsx
function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-footer"
className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
{...props}
/>
)
}Dialog function · typescript · L10-L14 (5 LOC)src/components/ui/dialog.tsx
function Dialog({
...props
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
return <DialogPrimitive.Root data-slot="dialog" {...props} />
}DialogTrigger function · typescript · L16-L20 (5 LOC)src/components/ui/dialog.tsx
function DialogTrigger({
...props
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
}DialogPortal function · typescript · L22-L26 (5 LOC)src/components/ui/dialog.tsx
function DialogPortal({
...props
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
}DialogClose function · typescript · L28-L32 (5 LOC)src/components/ui/dialog.tsx
function DialogClose({
...props
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
}Provenance: Repobility (https://repobility.com) — every score reproducible from /scan/
DialogOverlay function · typescript · L34-L48 (15 LOC)src/components/ui/dialog.tsx
function DialogOverlay({
className,
...props
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
return (
<DialogPrimitive.Overlay
data-slot="dialog-overlay"
className={cn(
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
className
)}
{...props}
/>
)
}DialogContent function · typescript · L50-L82 (33 LOC)src/components/ui/dialog.tsx
function DialogContent({
className,
children,
showCloseButton = true,
...props
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
showCloseButton?: boolean
}) {
return (
<DialogPortal data-slot="dialog-portal">
<DialogOverlay />
<DialogPrimitive.Content
data-slot="dialog-content"
className={cn(
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 outline-none sm:max-w-lg",
className
)}
{...props}
>
{children}
{showCloseButton && (
<DialogPrimitive.Close
data-slot="dialog-close"
className="ring-offset-background focus:ring-ring data-[state=open]:bg-aDialogHeader function · typescript · L84-L92 (9 LOC)src/components/ui/dialog.tsx
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="dialog-header"
className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
{...props}
/>
)
}