feat: add new theme (#157)
This commit is contained in:
@@ -28,7 +28,7 @@ export default function CampaignDetailsPage({
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center h-screen">
|
||||
<Spinner className="w-5 h-5 text-primary" />
|
||||
<Spinner className="w-5 h-5 text-foreground" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -94,7 +94,7 @@ export default function CampaignDetailsPage({
|
||||
<div className="capitalize">{card.status.toLowerCase()}</div>
|
||||
</div>
|
||||
<div className="flex justify-between items-end">
|
||||
<div className="text-primary font-light text-2xl font-mono">
|
||||
<div className="text-foreground font-light text-2xl font-mono">
|
||||
{card.count}
|
||||
</div>
|
||||
{card.status !== "total" ? (
|
||||
|
@@ -89,7 +89,7 @@ export default function CampaignList() {
|
||||
<TableRow key={campaign.id} className="">
|
||||
<TableCell className="font-medium">
|
||||
<Link
|
||||
className="underline underline-offset-4 decoration-dashed text-foreground hover:text-primary"
|
||||
className="underline underline-offset-4 decoration-dashed text-foreground hover:text-foreground"
|
||||
href={
|
||||
campaign.status === CampaignStatus.DRAFT
|
||||
? `/campaigns/${campaign.id}/edit`
|
||||
@@ -154,170 +154,3 @@ export default function CampaignList() {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// "use client";
|
||||
|
||||
// import {
|
||||
// Table,
|
||||
// TableHeader,
|
||||
// TableRow,
|
||||
// TableHead,
|
||||
// TableBody,
|
||||
// TableCell,
|
||||
// } from "@unsend/ui/src/table";
|
||||
// import { api } from "~/trpc/react";
|
||||
// import { useUrlState } from "~/hooks/useUrlState";
|
||||
// import { Button } from "@unsend/ui/src/button";
|
||||
// import Spinner from "@unsend/ui/src/spinner";
|
||||
// import { formatDistanceToNow } from "date-fns";
|
||||
// import { CampaignStatus } from "@prisma/client";
|
||||
// import DeleteCampaign from "./delete-campaign";
|
||||
// import Link from "next/link";
|
||||
// import DuplicateCampaign from "./duplicate-campaign";
|
||||
// import { motion } from "framer-motion";
|
||||
// import { useRouter } from "next/navigation";
|
||||
// import {
|
||||
// Select,
|
||||
// SelectTrigger,
|
||||
// SelectContent,
|
||||
// SelectItem,
|
||||
// } from "@unsend/ui/src/select";
|
||||
|
||||
// export default function CampaignList() {
|
||||
// const [page, setPage] = useUrlState("page", "1");
|
||||
// const [status, setStatus] = useUrlState("status");
|
||||
|
||||
// const pageNumber = Number(page);
|
||||
|
||||
// const campaignsQuery = api.campaign.getCampaigns.useQuery({
|
||||
// page: pageNumber,
|
||||
// status: status as CampaignStatus | null,
|
||||
// });
|
||||
|
||||
// const router = useRouter();
|
||||
|
||||
// return (
|
||||
// <div className="mt-10 flex flex-col gap-4">
|
||||
// <div className="flex justify-end">
|
||||
// <Select
|
||||
// value={status ?? "all"}
|
||||
// onValueChange={(val) => setStatus(val === "all" ? null : val)}
|
||||
// >
|
||||
// <SelectTrigger className="w-[180px] capitalize">
|
||||
// {status ? status.toLowerCase() : "All statuses"}
|
||||
// </SelectTrigger>
|
||||
// <SelectContent>
|
||||
// <SelectItem value="all" className=" capitalize">
|
||||
// All statuses
|
||||
// </SelectItem>
|
||||
// <SelectItem value={CampaignStatus.DRAFT} className=" capitalize">
|
||||
// Draft
|
||||
// </SelectItem>
|
||||
// <SelectItem
|
||||
// value={CampaignStatus.SCHEDULED}
|
||||
// className=" capitalize"
|
||||
// >
|
||||
// Scheduled
|
||||
// </SelectItem>
|
||||
// <SelectItem value={CampaignStatus.SENT} className=" capitalize">
|
||||
// Sent
|
||||
// </SelectItem>
|
||||
// </SelectContent>
|
||||
// </Select>
|
||||
// </div>
|
||||
|
||||
// {campaignsQuery.isLoading ? (
|
||||
// <div className="flex justify-center items-center mt-20">
|
||||
// <Spinner
|
||||
// className="w-5 h-5 text-primary"
|
||||
// innerSvgClass="stroke-primary"
|
||||
// />
|
||||
// </div>
|
||||
// ) : (
|
||||
// <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 ">
|
||||
// {campaignsQuery.data?.campaigns.map((campaign) => (
|
||||
// <motion.div
|
||||
// whileHover={{ scale: 1.01 }}
|
||||
// transition={{ type: "spring", stiffness: 600, damping: 10 }}
|
||||
// whileTap={{ scale: 0.99 }}
|
||||
// className="border rounded-xl shadow hover:shadow-lg"
|
||||
// key={campaign.id}
|
||||
// >
|
||||
// <div className="flex flex-col">
|
||||
// <Link
|
||||
// href={
|
||||
// campaign.status === CampaignStatus.DRAFT
|
||||
// ? `/campaigns/${campaign.id}/edit`
|
||||
// : `/campaigns/${campaign.id}`
|
||||
// }
|
||||
// >
|
||||
// <div className="h-40 overflow-hidden flex justify-center rounded-t-xl bg-muted/10">
|
||||
// <div
|
||||
// className="transform scale-[0.5] "
|
||||
// dangerouslySetInnerHTML={{ __html: campaign.html ?? "" }}
|
||||
// />
|
||||
// </div>
|
||||
// </Link>
|
||||
|
||||
// <div className="flex justify-between items-center shadow-[0px_-5px_25px_-8px_rgba(0,0,0,0.3)] rounded-xl -mt-2 z-10 bg-background">
|
||||
// <div
|
||||
// className="cursor-pointer w-full py-3 pl-4 flex gap-2 items-start"
|
||||
// onClick={() => router.push(`/campaigns/${campaign.id}`)}
|
||||
// >
|
||||
// <div className="flex flex-col gap-2">
|
||||
// <div className="flex gap-4">
|
||||
// <div className="font-semibold text-sm">
|
||||
// {campaign.name}
|
||||
// </div>
|
||||
// <div
|
||||
// className={`text-center px-4 rounded capitalize py-0.5 text-xs ${
|
||||
// campaign.status === CampaignStatus.DRAFT
|
||||
// ? "bg-gray-500/15 dark:bg-gray-600/10 text-gray-700 dark:text-gray-600/90 border border-gray-500/25 dark:border-gray-700/25"
|
||||
// : campaign.status === CampaignStatus.SENT
|
||||
// ? "bg-green-500/15 dark:bg-green-600/10 text-green-700 dark:text-green-600/90 border border-green-500/25 dark:border-green-700/25"
|
||||
// : "bg-yellow-500/15 dark:bg-yellow-600/10 text-yellow-700 dark:text-yellow-600/90 border border-yellow-500/25 dark:border-yellow-700/25"
|
||||
// }`}
|
||||
// >
|
||||
// {campaign.status.toLowerCase()}
|
||||
// </div>
|
||||
// </div>
|
||||
// <div className="text-muted-foreground text-xs">
|
||||
// {formatDistanceToNow(campaign.createdAt, {
|
||||
// addSuffix: true,
|
||||
// })}
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
|
||||
// <div className="flex gap-2 pr-4">
|
||||
// <DuplicateCampaign campaign={campaign} />
|
||||
// <DeleteCampaign campaign={campaign} />
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// </motion.div>
|
||||
// ))}
|
||||
// </div>
|
||||
// )}
|
||||
|
||||
// {campaignsQuery.data?.totalPage && campaignsQuery.data.totalPage > 1 ? (
|
||||
// <div className="flex gap-4 justify-end">
|
||||
// <Button
|
||||
// size="sm"
|
||||
// onClick={() => setPage((pageNumber - 1).toString())}
|
||||
// disabled={pageNumber === 1}
|
||||
// >
|
||||
// Previous
|
||||
// </Button>
|
||||
// <Button
|
||||
// size="sm"
|
||||
// onClick={() => setPage((pageNumber + 1).toString())}
|
||||
// disabled={pageNumber >= (campaignsQuery.data?.totalPage ?? 0)}
|
||||
// >
|
||||
// Next
|
||||
// </Button>
|
||||
// </div>
|
||||
// ) : null}
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
|
@@ -83,8 +83,10 @@ export const DeleteCampaign: React.FC<{
|
||||
<DialogTitle>Delete Campaign</DialogTitle>
|
||||
<DialogDescription>
|
||||
Are you sure you want to delete{" "}
|
||||
<span className="font-semibold text-primary">{campaign.name}</span>?
|
||||
You can't reverse this.
|
||||
<span className="font-semibold text-foreground">
|
||||
{campaign.name}
|
||||
</span>
|
||||
? You can't reverse this.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="py-2">
|
||||
|
@@ -54,7 +54,10 @@ export const DuplicateCampaign: React.FC<{
|
||||
<DialogTitle>Duplicate Campaign</DialogTitle>
|
||||
<DialogDescription>
|
||||
Are you sure you want to duplicate{" "}
|
||||
<span className="font-semibold text-primary">{campaign.name}</span>?
|
||||
<span className="font-semibold text-foreground">
|
||||
{campaign.name}
|
||||
</span>
|
||||
?
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="py-2">
|
||||
|
@@ -87,8 +87,10 @@ export const DeleteContact: React.FC<{
|
||||
<DialogTitle>Delete Contact</DialogTitle>
|
||||
<DialogDescription>
|
||||
Are you sure you want to delete{" "}
|
||||
<span className="font-semibold text-primary">{contact.email}</span>?
|
||||
You can't reverse this.
|
||||
<span className="font-semibold text-foreground">
|
||||
{contact.email}
|
||||
</span>
|
||||
? You can't reverse this.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="py-2">
|
||||
|
@@ -145,7 +145,7 @@ export const EditContact: React.FC<{
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
className="data-[state=checked]:bg-emerald-500"
|
||||
className="data-[state=checked]:bg-success"
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
|
@@ -86,7 +86,7 @@ export const DeleteContactBook: React.FC<{
|
||||
<DialogTitle>Delete Contact Book</DialogTitle>
|
||||
<DialogDescription>
|
||||
Are you sure you want to delete{" "}
|
||||
<span className="font-semibold text-primary">
|
||||
<span className="font-semibold text-foreground">
|
||||
{contactBook.name}
|
||||
</span>
|
||||
? You can't reverse this.
|
||||
|
@@ -78,7 +78,7 @@ export const EditContactBook: React.FC<{
|
||||
className="p-0 hover:bg-transparent"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<Edit className="h-4 w-4 text-primary/80 hover:text-primary/70" />
|
||||
<Edit className="h-4 w-4 text-foreground/80 hover:text-foreground/70" />
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
|
@@ -1,211 +1,26 @@
|
||||
"use client";
|
||||
|
||||
import { useSession } from "next-auth/react";
|
||||
import Link from "next/link";
|
||||
import { LogoutButton, NavButton } from "./nav-button";
|
||||
import {
|
||||
BookOpenText,
|
||||
BookUser,
|
||||
CircleUser,
|
||||
Code,
|
||||
Cog,
|
||||
Globe,
|
||||
Home,
|
||||
LayoutDashboard,
|
||||
LayoutTemplate,
|
||||
LineChart,
|
||||
Mail,
|
||||
Menu,
|
||||
Package,
|
||||
Package2,
|
||||
Server,
|
||||
Settings,
|
||||
ShoppingCart,
|
||||
Users,
|
||||
Volume2,
|
||||
} from "lucide-react";
|
||||
import { env } from "~/env";
|
||||
import { Sheet, SheetContent, SheetTrigger } from "@unsend/ui/src/sheet";
|
||||
import { Button } from "@unsend/ui/src/button";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from "@unsend/ui/src/dropdown-menu";
|
||||
import { ThemeSwitcher } from "~/components/theme/ThemeSwitcher";
|
||||
import { isCloud, isSelfHosted } from "~/utils/common";
|
||||
import { AppSidebar } from "~/components/AppSideBar";
|
||||
import { SidebarInset, SidebarTrigger } from "@unsend/ui/src/sidebar";
|
||||
import { SidebarProvider } from "@unsend/ui/src/sidebar";
|
||||
import { useIsMobile } from "@unsend/ui/src/hooks/use-mobile";
|
||||
|
||||
export function DashboardLayout({ children }: { children: React.ReactNode }) {
|
||||
const { data: session } = useSession();
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen w-full h-full">
|
||||
<div className="hidden bg-muted/20 md:block md:w-[230px]">
|
||||
<div className="flex h-full max-h-screen flex-col gap-2">
|
||||
<div className="flex h-14 gap-4 items-center px-4 lg:h-[60px] lg:px-6">
|
||||
<Link href="/" className="flex items-center gap-2 font-semibold">
|
||||
<span className=" text-lg">Unsend</span>
|
||||
</Link>
|
||||
<span className="text-[10px] text-muted-foreground bg-muted p-0.5 px-2 rounded-full">
|
||||
Early access
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex-1 h-full">
|
||||
<nav className=" flex-1 h-full flex-col justify-between items-center px-2 text-sm font-medium lg:px-4">
|
||||
<div className="h-[calc(100%-120px)]">
|
||||
<NavButton href="/dashboard">
|
||||
<LayoutDashboard className="h-4 w-4" />
|
||||
Dashboard
|
||||
</NavButton>
|
||||
|
||||
<NavButton href="/emails">
|
||||
<Mail className="h-4 w-4" />
|
||||
Emails
|
||||
</NavButton>
|
||||
|
||||
<NavButton href="/contacts">
|
||||
<BookUser className="h-4 w-4" />
|
||||
Contacts
|
||||
</NavButton>
|
||||
|
||||
<NavButton href="/templates">
|
||||
<LayoutTemplate className="h-4 w-4" />
|
||||
Templates
|
||||
</NavButton>
|
||||
|
||||
<NavButton href="/campaigns">
|
||||
<Volume2 className="h-4 w-4" />
|
||||
Campaigns
|
||||
</NavButton>
|
||||
|
||||
<NavButton href="/domains">
|
||||
<Globe className="h-4 w-4" />
|
||||
Domains
|
||||
</NavButton>
|
||||
|
||||
<NavButton href="/dev-settings">
|
||||
<Code className="h-4 w-4" />
|
||||
Developer settings
|
||||
</NavButton>
|
||||
|
||||
<NavButton href="/settings">
|
||||
<Cog className="h-4 w-4" />
|
||||
Settings
|
||||
</NavButton>
|
||||
|
||||
{isSelfHosted() || session?.user.isAdmin ? (
|
||||
<NavButton href="/admin">
|
||||
<Server className="h-4 w-4" />
|
||||
Admin
|
||||
</NavButton>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="pl-4 flex flex-col gap-2 w-full">
|
||||
<Link
|
||||
href="https://docs.unsend.dev"
|
||||
target="_blank"
|
||||
className="flex gap-2 items-center hover:text-primary text-muted-foreground"
|
||||
>
|
||||
<BookOpenText className="h-4 w-4" />
|
||||
<span className="">Docs</span>
|
||||
</Link>
|
||||
<LogoutButton />
|
||||
<div>
|
||||
<ThemeSwitcher />
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
<div className="mt-auto p-4"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-1 flex-col">
|
||||
<header className=" h-14 items-center gap-4 hidden bg-muted/20 px-4 lg:h-[60px] lg:px-6">
|
||||
<Sheet>
|
||||
<SheetTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
className="shrink-0 md:hidden"
|
||||
>
|
||||
<Menu className="h-5 w-5" />
|
||||
<span className="sr-only">Toggle navigation menu</span>
|
||||
</Button>
|
||||
</SheetTrigger>
|
||||
<SheetContent side="left" className="flex flex-col">
|
||||
<nav className="grid gap-2 text-lg font-medium">
|
||||
<Link
|
||||
href="#"
|
||||
className="flex items-center gap-2 text-lg font-semibold"
|
||||
>
|
||||
<Package2 className="h-6 w-6" />
|
||||
<span className="sr-only">Acme Inc</span>
|
||||
</Link>
|
||||
<Link
|
||||
href="#"
|
||||
className="mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
<Home className="h-5 w-5" />
|
||||
Dashboard
|
||||
</Link>
|
||||
<Link
|
||||
href="#"
|
||||
className="mx-[-0.65rem] flex items-center gap-4 rounded-xl bg-muted px-3 py-2 text-foreground hover:text-foreground"
|
||||
>
|
||||
<ShoppingCart className="h-5 w-5" />
|
||||
Orders
|
||||
</Link>
|
||||
<Link
|
||||
href="#"
|
||||
className="mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
<Package className="h-5 w-5" />
|
||||
Products
|
||||
</Link>
|
||||
<Link
|
||||
href="#"
|
||||
className="mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
<Users className="h-5 w-5" />
|
||||
Customers
|
||||
</Link>
|
||||
<Link
|
||||
href="#"
|
||||
className="mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
<LineChart className="h-5 w-5" />
|
||||
Analytics
|
||||
</Link>
|
||||
</nav>
|
||||
<div className="mt-auto"></div>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="secondary" size="icon" className="rounded-full">
|
||||
<CircleUser className="h-5 w-5" />
|
||||
<span className="sr-only">Toggle user menu</span>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuLabel>My Account</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem>Settings</DropdownMenuItem>
|
||||
<DropdownMenuItem>Support</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem>Logout</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</header>
|
||||
<main className="flex-1 overflow-y-auto h-full">
|
||||
<div className="flex flex-col gap-4 p-4 w-full lg:max-w-6xl mx-auto lg:gap-6 lg:p-6">
|
||||
<div className="h-full bg-sidebar-background">
|
||||
<SidebarProvider>
|
||||
<AppSidebar />
|
||||
<SidebarInset>
|
||||
<main className="flex-1 overflow-auto h-full p-4 px-40">
|
||||
{isMobile ? (
|
||||
<SidebarTrigger className="h-5 w-5 text-muted-foreground" />
|
||||
) : null}
|
||||
{children}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</main>
|
||||
</SidebarInset>
|
||||
</SidebarProvider>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@@ -235,11 +235,13 @@ const DashboardItemCard: React.FC<DashboardItemCardProps> = ({
|
||||
<div className=" capitalize">{status.toLowerCase()}</div>
|
||||
</div>
|
||||
<div className="flex justify-between items-end">
|
||||
<div className="text-primary font-light text-2xl font-mono">
|
||||
<div className="text-foreground font-light text-2xl font-mono">
|
||||
{count}
|
||||
</div>
|
||||
{status !== "total" ? (
|
||||
<div className="text-sm pb-1">{count > 0 ? (percentage * 100).toFixed(0) : 0}%</div>
|
||||
<div className="text-sm pb-1">
|
||||
{count > 0 ? (percentage * 100).toFixed(0) : 0}%
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -83,8 +83,8 @@ export const DeleteApiKey: React.FC<{
|
||||
<DialogTitle>Delete API key</DialogTitle>
|
||||
<DialogDescription>
|
||||
Are you sure you want to delete{" "}
|
||||
<span className="font-semibold text-primary">{apiKey.name}</span>?
|
||||
You can't reverse this.
|
||||
<span className="font-semibold text-foreground">{apiKey.name}</span>
|
||||
? You can't reverse this.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="py-2">
|
||||
|
@@ -15,9 +15,9 @@ export const SettingsNavButton: React.FC<{
|
||||
|
||||
if (comingSoon) {
|
||||
return (
|
||||
<div className="flex items-center justify-between hover:text-primary cursor-not-allowed mt-1">
|
||||
<div className="flex items-center justify-between hover:text-foreground cursor-not-allowed mt-1">
|
||||
<div
|
||||
className={`flex items-center gap-3 rounded-lg px-3 py-2 transition-all hover:text-primary cursor-not-allowed ${isActive ? " bg-secondary" : "text-muted-foreground"}`}
|
||||
className={`flex items-center gap-3 rounded-lg px-3 py-2 transition-all hover:text-foreground cursor-not-allowed ${isActive ? " bg-secondary" : "text-muted-foreground"}`}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
@@ -31,7 +31,7 @@ export const SettingsNavButton: React.FC<{
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
className={`flex text-sm items-center mt-1 gap-3 rounded px-2 py-1 transition-all hover:text-primary ${isActive ? " bg-accent" : "text-muted-foreground"}`}
|
||||
className={`flex text-sm items-center mt-1 gap-3 rounded px-2 py-1 transition-all hover:text-foreground ${isActive ? " bg-accent" : "text-muted-foreground"}`}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
|
@@ -5,9 +5,10 @@ import { Input } from "@unsend/ui/src/input";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription, DialogHeader,
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger
|
||||
DialogTrigger,
|
||||
} from "@unsend/ui/src/dialog";
|
||||
|
||||
import {
|
||||
@@ -84,8 +85,8 @@ export const DeleteDomain: React.FC<{ domain: Domain }> = ({ domain }) => {
|
||||
<DialogTitle>Delete domain</DialogTitle>
|
||||
<DialogDescription>
|
||||
Are you sure you want to delete{" "}
|
||||
<span className="font-semibold text-primary">{domain.name}</span>?
|
||||
You can't reverse this.
|
||||
<span className="font-semibold text-foreground">{domain.name}</span>
|
||||
? You can't reverse this.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<Form {...domainForm}>
|
||||
|
@@ -274,7 +274,7 @@ const DomainSettings: React.FC<{ domain: Domain }> = ({ domain }) => {
|
||||
<Switch
|
||||
checked={clickTracking}
|
||||
onCheckedChange={handleClickTrackingChange}
|
||||
className="data-[state=checked]:bg-emerald-500"
|
||||
className="data-[state=checked]:bg-success"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -288,7 +288,7 @@ const DomainSettings: React.FC<{ domain: Domain }> = ({ domain }) => {
|
||||
<Switch
|
||||
checked={openTracking}
|
||||
onCheckedChange={handleOpenTrackingChange}
|
||||
className="data-[state=checked]:bg-emerald-500"
|
||||
className="data-[state=checked]:bg-success"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
@@ -104,7 +104,7 @@ const DomainItem: React.FC<{ domain: Domain }> = ({ domain }) => {
|
||||
<Switch
|
||||
checked={clickTracking}
|
||||
onCheckedChange={handleClickTrackingChange}
|
||||
className="data-[state=checked]:bg-emerald-500"
|
||||
className="data-[state=checked]:bg-success"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex gap-2 items-center">
|
||||
@@ -112,7 +112,7 @@ const DomainItem: React.FC<{ domain: Domain }> = ({ domain }) => {
|
||||
<Switch
|
||||
checked={openTracking}
|
||||
onCheckedChange={handleOpenTrackingChange}
|
||||
className="data-[state=checked]:bg-emerald-500"
|
||||
className="data-[state=checked]:bg-success"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -115,7 +115,7 @@ export default function EmailDetails({ emailId }: { emailId: string }) {
|
||||
<div className="text-xs text-muted-foreground mt-2">
|
||||
{formatDate(evt.createdAt, "MMM dd, hh:mm a")}
|
||||
</div>
|
||||
<div className="mt-1 text-primary/80">
|
||||
<div className="mt-1 text-foreground/80">
|
||||
<EmailStatusText
|
||||
status={evt.status}
|
||||
data={evt.data}
|
||||
|
@@ -1,53 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { LogOut } from "lucide-react";
|
||||
import { signOut } from "next-auth/react";
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import React from "react";
|
||||
|
||||
export const NavButton: React.FC<{
|
||||
href: string;
|
||||
children: React.ReactNode;
|
||||
comingSoon?: boolean;
|
||||
}> = ({ href, children, comingSoon }) => {
|
||||
const pathname = usePathname();
|
||||
|
||||
const isActive = pathname?.startsWith(href);
|
||||
|
||||
if (comingSoon) {
|
||||
return (
|
||||
<div className="flex items-center justify-between hover:text-primary cursor-not-allowed mt-1">
|
||||
<div
|
||||
className={`flex items-center gap-3 rounded-lg px-3 py-2 transition-all hover:text-primary cursor-not-allowed ${isActive ? " bg-secondary" : "text-muted-foreground"}`}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
<div className="text-muted-foreground px-4 py-0.5 text-xs bg-muted rounded-full">
|
||||
soon
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
className={`flex items-center mt-1 gap-3 rounded-lg px-3 py-2 transition-all hover:text-primary ${isActive ? " bg-secondary" : "text-muted-foreground"}`}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
export const LogoutButton: React.FC = () => {
|
||||
return (
|
||||
<button
|
||||
className={` w-full justify-start flex items-center gap-2 rounded-lg py-2 transition-all hover:text-primary text-muted-foreground`}
|
||||
onClick={() => signOut()}
|
||||
>
|
||||
<LogOut className="h-4 w-4" />
|
||||
Logout
|
||||
</button>
|
||||
);
|
||||
};
|
@@ -55,7 +55,10 @@ export const DeleteTeamInvite: React.FC<{
|
||||
<DialogTitle>Cancel Invite</DialogTitle>
|
||||
<DialogDescription>
|
||||
Are you sure you want to cancel the invite for{" "}
|
||||
<span className="font-semibold text-primary">{invite.email}</span>?
|
||||
<span className="font-semibold text-foreground">
|
||||
{invite.email}
|
||||
</span>
|
||||
?
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="flex justify-end gap-4 mt-6">
|
||||
|
@@ -83,8 +83,10 @@ export const DeleteTemplate: React.FC<{
|
||||
<DialogTitle>Delete Template</DialogTitle>
|
||||
<DialogDescription>
|
||||
Are you sure you want to delete{" "}
|
||||
<span className="font-semibold text-primary">{template.name}</span>?
|
||||
You can't reverse this.
|
||||
<span className="font-semibold text-foreground">
|
||||
{template.name}
|
||||
</span>
|
||||
? You can't reverse this.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="py-2">
|
||||
|
@@ -54,7 +54,10 @@ export const DuplicateTemplate: React.FC<{
|
||||
<DialogTitle>Duplicate Template</DialogTitle>
|
||||
<DialogDescription>
|
||||
Are you sure you want to duplicate{" "}
|
||||
<span className="font-semibold text-primary">{template.name}</span>?
|
||||
<span className="font-semibold text-foreground">
|
||||
{template.name}
|
||||
</span>
|
||||
?
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="py-2">
|
||||
|
@@ -57,7 +57,7 @@ export default function TemplateList() {
|
||||
<TableRow key={template.id} className="">
|
||||
<TableCell className="font-medium">
|
||||
<Link
|
||||
className="underline underline-offset-4 decoration-dashed text-foreground hover:text-primary"
|
||||
className="underline underline-offset-4 decoration-dashed text-foreground hover:text-foreground"
|
||||
href={`/templates/${template.id}/edit`}
|
||||
>
|
||||
{template.name}
|
||||
|
Reference in New Issue
Block a user