refactor: migrate authentication system and update Drizzle schema.

This commit is contained in:
2025-11-29 02:26:26 -05:00
parent c88e5d9d82
commit 3ebec7aa4a
36 changed files with 603 additions and 440 deletions
+29 -28
View File
@@ -136,9 +136,9 @@ export default function SendEmailPage() {
action:
canRetry && retryCount < 2
? {
label: "Retry",
onClick: () => handleRetry(),
}
label: "Retry",
onClick: () => handleRetry(),
}
: undefined,
});
@@ -150,31 +150,31 @@ export default function SendEmailPage() {
const invoice = useMemo(() => {
return invoiceData
? {
id: invoiceData.id,
invoiceNumber: invoiceData.invoiceNumber,
issueDate: invoiceData.issueDate,
dueDate: invoiceData.dueDate,
status: invoiceData.status,
taxRate: invoiceData.taxRate,
client: invoiceData.client
? {
name: invoiceData.client.name,
email: invoiceData.client.email,
}
: undefined,
business: invoiceData.business
? {
name: invoiceData.business.name,
nickname: invoiceData.business.nickname,
email: invoiceData.business.email,
}
: undefined,
items: invoiceData.items?.map((item) => ({
id: item.id,
hours: item.hours,
rate: item.rate,
})),
}
id: invoiceData.id,
invoiceNumber: invoiceData.invoiceNumber,
issueDate: invoiceData.issueDate,
dueDate: invoiceData.dueDate,
status: invoiceData.status,
taxRate: invoiceData.taxRate,
client: invoiceData.client
? {
name: invoiceData.client.name,
email: invoiceData.client.email,
}
: undefined,
business: invoiceData.business
? {
name: invoiceData.business.name,
nickname: invoiceData.business.nickname,
email: invoiceData.business.email,
}
: undefined,
items: invoiceData.items?.map((item) => ({
id: item.id,
hours: item.hours,
rate: item.rate,
})),
}
: undefined;
}, [invoiceData]);
@@ -184,6 +184,7 @@ export default function SendEmailPage() {
// Set default subject
const defaultSubject = `Invoice ${invoice.invoiceNumber} from ${invoice.business?.name ?? "Your Business"}`;
// eslint-disable-next-line react-hooks/set-state-in-effect
setSubject(defaultSubject);
// Set default content (empty since template handles everything)
+18 -16
View File
@@ -16,7 +16,8 @@ import { Button } from "~/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
import { Skeleton } from "~/components/ui/skeleton";
import { getEffectiveInvoiceStatus } from "~/lib/invoice-status";
import { auth } from "~/server/auth";
import { auth } from "~/lib/auth";
import { headers } from "next/headers";
import { HydrateClient, api } from "~/trpc/server";
import type { StoredInvoiceStatus } from "~/types/invoice";
import { RevenueChart } from "~/app/dashboard/_components/revenue-chart";
@@ -126,15 +127,15 @@ async function DashboardStats() {
const pendingChange =
lastMonthInvoices.length > 0
? ((pendingInvoices.length -
lastMonthInvoices.filter((invoice) => {
const status = getEffectiveInvoiceStatus(
invoice.status as StoredInvoiceStatus,
invoice.dueDate,
);
return status === "sent" || status === "overdue";
}).length) /
lastMonthInvoices.length) *
100
lastMonthInvoices.filter((invoice) => {
const status = getEffectiveInvoiceStatus(
invoice.status as StoredInvoiceStatus,
invoice.dueDate,
);
return status === "sent" || status === "overdue";
}).length) /
lastMonthInvoices.length) *
100
: pendingInvoices.length > 0
? 100
: 0;
@@ -323,11 +324,10 @@ function QuickActions() {
<Link
key={action.title}
href={action.href}
className={`hover-lift flex w-full items-start space-x-3 rounded-lg border p-4 transition-colors ${
action.featured
? "border-foreground/20 bg-muted/50 hover:bg-muted"
: "border-border bg-background hover:bg-muted/50"
}`}
className={`hover-lift flex w-full items-start space-x-3 rounded-lg border p-4 transition-colors ${action.featured
? "border-foreground/20 bg-muted/50 hover:bg-muted"
: "border-border bg-background hover:bg-muted/50"
}`}
>
<Icon className="h-5 w-5 flex-shrink-0" />
<div className="min-w-0 flex-1">
@@ -624,7 +624,9 @@ function CardSkeleton() {
}
export default async function DashboardPage() {
const session = await auth();
const session = await auth.api.getSession({
headers: await headers(),
});
const firstName = session?.user?.name?.split(" ")[0] ?? "User";
return (
@@ -18,7 +18,7 @@ import {
User,
Users,
} from "lucide-react";
import { useSession } from "next-auth/react";
import { authClient } from "~/lib/auth-client";
import * as React from "react";
import { useState } from "react";
@@ -66,7 +66,7 @@ import { AppearanceSettings } from "./appearance-settings";
import { useAnimationPreferences } from "~/components/providers/animation-preferences-provider";
export function SettingsContent() {
const { data: session } = useSession();
const { data: session } = authClient.useSession();
const [name, setName] = useState("");
const [deleteConfirmText, setDeleteConfirmText] = useState("");
const [importData, setImportData] = useState("");
@@ -41,6 +41,7 @@ export function ThemeSelector() {
"h-8 w-8 rounded-full border-2",
colorTheme === t.name && "border-primary",
)}
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
onClick={() => setColorTheme(t.name as any)}
style={{ backgroundColor: t.hex }}
>