mirror of
https://github.com/soconnor0919/beenvoice.git
synced 2026-02-05 00:06:36 -05:00
fix: resolve majority of lint errors across codebase
- Remove unused imports from page.tsx, clients/page.tsx, invoices/page.tsx - Remove unused imports from invoice-form.tsx, invoice-workspace.tsx - Move CustomTooltip outside component in revenue-chart.tsx (fixes react-hooks/static-components) - Fix type safety in umami.ts (any -> unknown) - Fix type safety in sidebar-provider.tsx (add type assertion) - Add no-op comments to empty fallback functions in animation-preferences-provider.tsx - Fix type safety in invoice-workspace.tsx (any[] -> typed array) Note: dashboard/page.tsx still has ~55 type safety warnings related to 'any' types in stats/invoice data. These are pre-existing and would require significant refactoring of the dashboard data flow to properly type. TypeScript compilation passes.
This commit is contained in:
@@ -10,13 +10,7 @@ import {
|
|||||||
} from "recharts";
|
} from "recharts";
|
||||||
import { useAnimationPreferences } from "~/components/providers/animation-preferences-provider";
|
import { useAnimationPreferences } from "~/components/providers/animation-preferences-provider";
|
||||||
|
|
||||||
interface Invoice {
|
|
||||||
id: string;
|
|
||||||
totalAmount: number;
|
|
||||||
issueDate: Date | string;
|
|
||||||
status: string;
|
|
||||||
dueDate: Date | string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface RevenueChartProps {
|
interface RevenueChartProps {
|
||||||
data: {
|
data: {
|
||||||
@@ -26,6 +20,41 @@ interface RevenueChartProps {
|
|||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CustomTooltip = ({
|
||||||
|
active,
|
||||||
|
payload,
|
||||||
|
label,
|
||||||
|
}: {
|
||||||
|
active?: boolean;
|
||||||
|
payload?: Array<{ payload: { revenue: number } }>;
|
||||||
|
label?: string;
|
||||||
|
}) => {
|
||||||
|
const formatCurrency = (value: number) => {
|
||||||
|
return new Intl.NumberFormat("en-US", {
|
||||||
|
style: "currency",
|
||||||
|
currency: "USD",
|
||||||
|
minimumFractionDigits: 0,
|
||||||
|
maximumFractionDigits: 0,
|
||||||
|
}).format(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (active && payload?.length) {
|
||||||
|
const data = payload[0]!.payload;
|
||||||
|
return (
|
||||||
|
<div className="bg-card border-border rounded-lg border p-3 shadow-lg">
|
||||||
|
<p className="font-medium">{label}</p>
|
||||||
|
<p style={{ color: "hsl(0, 0%, 60%)" }}>
|
||||||
|
Revenue: {formatCurrency(data.revenue)}
|
||||||
|
</p>
|
||||||
|
<p className="text-muted-foreground text-sm">
|
||||||
|
{/* Count not available in aggregated view currently */}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
export function RevenueChart({ data }: RevenueChartProps) {
|
export function RevenueChart({ data }: RevenueChartProps) {
|
||||||
// Use data directly
|
// Use data directly
|
||||||
const chartData = data;
|
const chartData = data;
|
||||||
@@ -39,32 +68,6 @@ export function RevenueChart({ data }: RevenueChartProps) {
|
|||||||
}).format(value);
|
}).format(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const CustomTooltip = ({
|
|
||||||
active,
|
|
||||||
payload,
|
|
||||||
label,
|
|
||||||
}: {
|
|
||||||
active?: boolean;
|
|
||||||
payload?: Array<{ payload: { revenue: number } }>;
|
|
||||||
label?: string;
|
|
||||||
}) => {
|
|
||||||
if (active && payload?.length) {
|
|
||||||
const data = payload[0]!.payload;
|
|
||||||
return (
|
|
||||||
<div className="bg-card border-border rounded-lg border p-3 shadow-lg">
|
|
||||||
<p className="font-medium">{label}</p>
|
|
||||||
<p style={{ color: "hsl(0, 0%, 60%)" }}>
|
|
||||||
Revenue: {formatCurrency(data.revenue)}
|
|
||||||
</p>
|
|
||||||
<p className="text-muted-foreground text-sm">
|
|
||||||
{/* Count not available in aggregated view currently */}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
const { prefersReducedMotion, animationSpeedMultiplier } =
|
const { prefersReducedMotion, animationSpeedMultiplier } =
|
||||||
useAnimationPreferences();
|
useAnimationPreferences();
|
||||||
if (chartData.length === 0) {
|
if (chartData.length === 0) {
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { PageHeader } from "~/components/layout/page-header";
|
|||||||
import { Button } from "~/components/ui/button";
|
import { Button } from "~/components/ui/button";
|
||||||
import { HydrateClient } from "~/trpc/server";
|
import { HydrateClient } from "~/trpc/server";
|
||||||
import { ClientsTable } from "./_components/clients-table";
|
import { ClientsTable } from "./_components/clients-table";
|
||||||
import { Card, CardContent } from "~/components/ui/card";
|
|
||||||
|
|
||||||
export default async function ClientsPage() {
|
export default async function ClientsPage() {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { PageHeader } from "~/components/layout/page-header";
|
|||||||
import { Plus, Upload } from "lucide-react";
|
import { Plus, Upload } from "lucide-react";
|
||||||
import { InvoicesDataTable } from "./_components/invoices-data-table";
|
import { InvoicesDataTable } from "./_components/invoices-data-table";
|
||||||
import { DataTableSkeleton } from "~/components/data/data-table";
|
import { DataTableSkeleton } from "~/components/data/data-table";
|
||||||
import { Card, CardContent } from "~/components/ui/card";
|
|
||||||
|
|
||||||
// Invoices Table Component
|
// Invoices Table Component
|
||||||
async function InvoicesTable() {
|
async function InvoicesTable() {
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import {
|
|||||||
Shield,
|
Shield,
|
||||||
BarChart3,
|
BarChart3,
|
||||||
Rocket,
|
Rocket,
|
||||||
ChevronRight,
|
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
|
|
||||||
export default function HomePage() {
|
export default function HomePage() {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { useState, useEffect, useRef } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { Button } from "~/components/ui/button";
|
import { Button } from "~/components/ui/button";
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
|
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { cn } from "~/lib/utils";
|
import { cn } from "~/lib/utils";
|
||||||
import { Button } from "~/components/ui/button";
|
import { Button } from "~/components/ui/button";
|
||||||
import { Card, CardContent } from "~/components/ui/card";
|
import { List, Calendar as CalendarIcon } from "lucide-react";
|
||||||
import { ScrollArea } from "~/components/ui/scroll-area";
|
|
||||||
import { List, Calendar as CalendarIcon, Plus } from "lucide-react";
|
|
||||||
import { InvoiceLineItems } from "../invoice-line-items";
|
import { InvoiceLineItems } from "../invoice-line-items";
|
||||||
import { InvoiceCalendarView } from "../invoice-calendar-view";
|
import { InvoiceCalendarView } from "../invoice-calendar-view";
|
||||||
import type { InvoiceFormData } from "./types";
|
import type { InvoiceFormData } from "./types";
|
||||||
@@ -19,7 +17,7 @@ interface InvoiceWorkspaceProps {
|
|||||||
updateItem: (index: number, field: string, value: string | number | Date) => void;
|
updateItem: (index: number, field: string, value: string | number | Date) => void;
|
||||||
moveItemUp: (index: number) => void;
|
moveItemUp: (index: number) => void;
|
||||||
moveItemDown: (index: number) => void;
|
moveItemDown: (index: number) => void;
|
||||||
reorderItems: (items: any[]) => void;
|
reorderItems: (items: InvoiceFormData['items']) => void;
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export function SidebarProvider({ children }: { children: React.ReactNode }) {
|
|||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const saved = localStorage.getItem("sidebar-collapsed");
|
const saved = localStorage.getItem("sidebar-collapsed");
|
||||||
if (saved) {
|
if (saved) {
|
||||||
setIsCollapsed(JSON.parse(saved));
|
setIsCollapsed(JSON.parse(saved) as boolean);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|||||||
@@ -403,9 +403,9 @@ export function useAnimationPreferences(): AnimationPreferencesContextValue {
|
|||||||
return {
|
return {
|
||||||
prefersReducedMotion: false,
|
prefersReducedMotion: false,
|
||||||
animationSpeedMultiplier: 1,
|
animationSpeedMultiplier: 1,
|
||||||
updatePreferences: () => { },
|
updatePreferences: () => { /* no-op fallback */ },
|
||||||
setPrefersReducedMotion: () => { },
|
setPrefersReducedMotion: () => { /* no-op fallback */ },
|
||||||
setAnimationSpeedMultiplier: () => { },
|
setAnimationSpeedMultiplier: () => { /* no-op fallback */ },
|
||||||
isUpdating: false,
|
isUpdating: false,
|
||||||
lastSyncedAt: null,
|
lastSyncedAt: null,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ type UmamiPayload = {
|
|||||||
url: string;
|
url: string;
|
||||||
website: string;
|
website: string;
|
||||||
name: string;
|
name: string;
|
||||||
data?: Record<string, any>;
|
data?: Record<string, unknown>;
|
||||||
};
|
};
|
||||||
type: "event";
|
type: "event";
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function trackServerEvent(
|
export async function trackServerEvent(
|
||||||
eventName: string,
|
eventName: string,
|
||||||
eventData?: Record<string, any>,
|
eventData?: Record<string, unknown>,
|
||||||
) {
|
) {
|
||||||
if (!env.NEXT_PUBLIC_UMAMI_WEBSITE_ID || !env.NEXT_PUBLIC_UMAMI_SCRIPT_URL) {
|
if (!env.NEXT_PUBLIC_UMAMI_WEBSITE_ID || !env.NEXT_PUBLIC_UMAMI_SCRIPT_URL) {
|
||||||
console.warn("Umami not configured, skipping server-side event tracking");
|
console.warn("Umami not configured, skipping server-side event tracking");
|
||||||
|
|||||||
Reference in New Issue
Block a user