Add customer management UI components

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 9111ef36-26c8-4085-84ca-a35dc1fec1b5
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7083d608-d6d3-4a6a-9a27-6286c5109627/7e31146a-cd1d-4738-8630-47e80ea2b8a0.jpg
This commit is contained in:
alphaeusmote
2025-04-11 21:08:27 +00:00
parent d78828e6cd
commit e104540022
3 changed files with 296 additions and 0 deletions
@@ -0,0 +1,80 @@
import { useState } from "react";
import { format } from "date-fns";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { useCustomer } from "@/context/customer-context";
import { Customer } from "@shared/schema";
import { Calendar, Server, Users } from "lucide-react";
interface CustomerListCardProps {
customers: Customer[];
}
export function CustomerListCard({ customers }: CustomerListCardProps) {
const { currentCustomer, setCurrentCustomer } = useCustomer();
if (!customers || customers.length === 0) {
return (
<Card>
<CardHeader>
<CardTitle>Customers</CardTitle>
<CardDescription>
You don't have any customers yet.
</CardDescription>
</CardHeader>
<CardContent>
<div className="flex items-center justify-center h-40">
<p className="text-muted-foreground">
Create a customer in the settings page.
</p>
</div>
</CardContent>
</Card>
);
}
return (
<Card>
<CardHeader>
<CardTitle>Customers</CardTitle>
<CardDescription>
Select a customer to manage their domains and DNS records
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-2">
{customers.map((customer) => (
<div
key={customer.id}
className={`p-3 rounded-md cursor-pointer transition-colors border ${
currentCustomer?.id === customer.id ? "bg-accent border-primary/50" : "hover:bg-muted/50 border-transparent"
}`}
onClick={() => setCurrentCustomer(customer)}
>
<div className="flex justify-between items-center mb-2">
<div className="font-medium flex items-center">
<Server className="h-4 w-4 mr-2 text-primary" />
{customer.name}
{!customer.isActive && (
<span className="ml-2 text-xs bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-300 rounded-full px-2 py-0.5">
Inactive
</span>
)}
</div>
</div>
<div className="text-xs text-muted-foreground flex flex-wrap gap-x-3">
<div className="flex items-center">
<Users className="h-3 w-3 mr-1" />
<span>3 Members</span>
</div>
<div className="flex items-center">
<Calendar className="h-3 w-3 mr-1" />
<span>Created {format(new Date(customer.createdAt), 'MMM d, yyyy')}</span>
</div>
</div>
</div>
))}
</div>
</CardContent>
</Card>
);
}
@@ -0,0 +1,63 @@
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { useCustomer } from "@/context/customer-context";
import { ChevronDown } from "lucide-react";
export function CustomerSelector() {
const { customers, currentCustomer, setCurrentCustomer, isLoading } = useCustomer();
if (isLoading) {
return (
<div className="w-full flex items-center justify-between px-3 py-2 text-sm font-medium rounded-md bg-secondary text-secondary-foreground opacity-70 animate-pulse">
<div className="flex items-center">
<span className="w-2 h-2 bg-muted rounded-full mr-2"></span>
<span>Loading...</span>
</div>
</div>
);
}
if (!currentCustomer || customers.length === 0) {
return (
<div className="w-full flex items-center justify-between px-3 py-2 text-sm font-medium rounded-md bg-secondary text-secondary-foreground">
<div className="flex items-center">
<span className="w-2 h-2 bg-warning rounded-full mr-2"></span>
<span>No Customer</span>
</div>
</div>
);
}
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="w-full flex items-center justify-between px-3 py-2 text-sm font-medium rounded-md hover:bg-accent">
<div className="flex items-center">
<span className="w-2 h-2 bg-success rounded-full mr-2"></span>
<span>{currentCustomer.name}</span>
</div>
<ChevronDown className="h-4 w-4 opacity-50" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start" className="w-64">
{customers.map((customer) => (
<DropdownMenuItem
key={customer.id}
onClick={() => setCurrentCustomer(customer)}
className={customer.id === currentCustomer.id ? "bg-muted" : ""}
>
<div className="flex items-center">
<span className={`w-2 h-2 rounded-full mr-2 ${customer.isActive ? "bg-success" : "bg-warning"}`}></span>
<span>{customer.name}</span>
</div>
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
);
}