refactor: migrate from ESLint to Biome and extract SQL queries to data.ts

- Replace ESLint with Biome for linting and formatting
- Configure Biome with tabs, double quotes, and organized imports
- Move all SQL/Drizzle queries from page.tsx files to data.ts files
- Create new data.ts files for: ajustes, dashboard, relatorios/categorias
- Update existing data.ts files: extrato, fatura (add lancamentos queries)
- Remove all drizzle-orm imports from page.tsx files
- Update README.md with new tooling info

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Felipe Coutinho
2026-01-27 13:15:37 +00:00
parent 8ffe61c59b
commit a7f63fb77a
442 changed files with 66141 additions and 69292 deletions

View File

@@ -1,154 +1,154 @@
"use client";
import { useState } from "react";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
RiBugLine,
RiExternalLinkLine,
RiLightbulbLine,
RiMessageLine,
RiQuestionLine,
RiStarLine,
} from "@remixicon/react";
import { useState } from "react";
import { Button, buttonVariants } from "@/components/ui/button";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";
import {
RiMessageLine,
RiBugLine,
RiLightbulbLine,
RiQuestionLine,
RiStarLine,
RiExternalLinkLine,
} from "@remixicon/react";
const GITHUB_REPO_BASE = "https://github.com/felipegcoutinho/opensheets-app";
const GITHUB_DISCUSSIONS_BASE = `${GITHUB_REPO_BASE}/discussions/new`;
const GITHUB_ISSUES_URL = `${GITHUB_REPO_BASE}/issues/new`;
const feedbackCategories = [
{
id: "bug",
title: "Reportar Bug",
icon: RiBugLine,
description: "Encontrou algo que não está funcionando?",
color: "text-red-500 dark:text-red-400",
url: GITHUB_ISSUES_URL,
},
{
id: "idea",
title: "Sugerir Feature",
icon: RiLightbulbLine,
description: "Tem uma ideia para melhorar o app?",
color: "text-yellow-500 dark:text-yellow-400",
url: `${GITHUB_DISCUSSIONS_BASE}?category=ideias`,
},
{
id: "question",
title: "Dúvidas/Suporte",
icon: RiQuestionLine,
description: "Precisa de ajuda com alguma coisa?",
color: "text-blue-500 dark:text-blue-400",
url: `${GITHUB_DISCUSSIONS_BASE}?category=q-a`,
},
{
id: "experience",
title: "Compartilhar Experiência",
icon: RiStarLine,
description: "Como o OpenSheets tem ajudado você?",
color: "text-purple-500 dark:text-purple-400",
url: `${GITHUB_DISCUSSIONS_BASE}?category=sua-experiencia`,
},
{
id: "bug",
title: "Reportar Bug",
icon: RiBugLine,
description: "Encontrou algo que não está funcionando?",
color: "text-red-500 dark:text-red-400",
url: GITHUB_ISSUES_URL,
},
{
id: "idea",
title: "Sugerir Feature",
icon: RiLightbulbLine,
description: "Tem uma ideia para melhorar o app?",
color: "text-yellow-500 dark:text-yellow-400",
url: `${GITHUB_DISCUSSIONS_BASE}?category=ideias`,
},
{
id: "question",
title: "Dúvidas/Suporte",
icon: RiQuestionLine,
description: "Precisa de ajuda com alguma coisa?",
color: "text-blue-500 dark:text-blue-400",
url: `${GITHUB_DISCUSSIONS_BASE}?category=q-a`,
},
{
id: "experience",
title: "Compartilhar Experiência",
icon: RiStarLine,
description: "Como o OpenSheets tem ajudado você?",
color: "text-purple-500 dark:text-purple-400",
url: `${GITHUB_DISCUSSIONS_BASE}?category=sua-experiencia`,
},
];
export function FeedbackDialog() {
const [open, setOpen] = useState(false);
const [open, setOpen] = useState(false);
const handleCategoryClick = (url: string) => {
window.open(url, "_blank", "noopener,noreferrer");
setOpen(false);
};
const handleCategoryClick = (url: string) => {
window.open(url, "_blank", "noopener,noreferrer");
setOpen(false);
};
return (
<Dialog open={open} onOpenChange={setOpen}>
<Tooltip>
<TooltipTrigger asChild>
<DialogTrigger asChild>
<Button
variant="ghost"
size="icon"
className={cn(
buttonVariants({ variant: "ghost", size: "icon-sm" }),
"group relative text-muted-foreground transition-all duration-200",
"hover:text-foreground focus-visible:ring-2 focus-visible:ring-primary/40",
"data-[state=open]:bg-accent/60 data-[state=open]:text-foreground border"
)}
>
<RiMessageLine className="h-5 w-5" />
</Button>
</DialogTrigger>
</TooltipTrigger>
<TooltipContent>Enviar Feedback</TooltipContent>
</Tooltip>
return (
<Dialog open={open} onOpenChange={setOpen}>
<Tooltip>
<TooltipTrigger asChild>
<DialogTrigger asChild>
<Button
variant="ghost"
size="icon"
className={cn(
buttonVariants({ variant: "ghost", size: "icon-sm" }),
"group relative text-muted-foreground transition-all duration-200",
"hover:text-foreground focus-visible:ring-2 focus-visible:ring-primary/40",
"data-[state=open]:bg-accent/60 data-[state=open]:text-foreground border",
)}
>
<RiMessageLine className="h-5 w-5" />
</Button>
</DialogTrigger>
</TooltipTrigger>
<TooltipContent>Enviar Feedback</TooltipContent>
</Tooltip>
<DialogContent className="sm:max-w-[500px]">
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<RiMessageLine className="h-5 w-5" />
Enviar Feedback
</DialogTitle>
<DialogDescription>
Sua opinião é muito importante! Escolha o tipo de feedback que
deseja compartilhar.
</DialogDescription>
</DialogHeader>
<DialogContent className="sm:max-w-[500px]">
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<RiMessageLine className="h-5 w-5" />
Enviar Feedback
</DialogTitle>
<DialogDescription>
Sua opinião é muito importante! Escolha o tipo de feedback que
deseja compartilhar.
</DialogDescription>
</DialogHeader>
<div className="grid gap-3 py-4">
{feedbackCategories.map((item) => {
const Icon = item.icon;
return (
<button
key={item.id}
onClick={() => handleCategoryClick(item.url)}
className={cn(
"flex items-start gap-3 p-4 rounded-lg border transition-all",
"hover:border-primary hover:bg-accent/50",
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary"
)}
>
<div
className={cn(
"flex h-10 w-10 shrink-0 items-center justify-center rounded-full",
"bg-muted"
)}
>
<Icon className={cn("h-5 w-5", item.color)} />
</div>
<div className="flex-1 text-left space-y-1">
<h3 className="font-semibold text-sm flex items-center gap-2">
{item.title}
<RiExternalLinkLine className="h-3.5 w-3.5 text-muted-foreground" />
</h3>
<p className="text-sm text-muted-foreground">
{item.description}
</p>
</div>
</button>
);
})}
</div>
<div className="grid gap-3 py-4">
{feedbackCategories.map((item) => {
const Icon = item.icon;
return (
<button
key={item.id}
onClick={() => handleCategoryClick(item.url)}
className={cn(
"flex items-start gap-3 p-4 rounded-lg border transition-all",
"hover:border-primary hover:bg-accent/50",
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary",
)}
>
<div
className={cn(
"flex h-10 w-10 shrink-0 items-center justify-center rounded-full",
"bg-muted",
)}
>
<Icon className={cn("h-5 w-5", item.color)} />
</div>
<div className="flex-1 text-left space-y-1">
<h3 className="font-semibold text-sm flex items-center gap-2">
{item.title}
<RiExternalLinkLine className="h-3.5 w-3.5 text-muted-foreground" />
</h3>
<p className="text-sm text-muted-foreground">
{item.description}
</p>
</div>
</button>
);
})}
</div>
<div className="flex items-start gap-2 p-3 bg-muted/50 rounded-lg text-xs text-muted-foreground">
<RiExternalLinkLine className="h-4 w-4 shrink-0 mt-0.5" />
<p>
Você será redirecionado para o GitHub Discussions onde poderá
escrever seu feedback. É necessário ter uma conta no GitHub.
</p>
</div>
</DialogContent>
</Dialog>
);
<div className="flex items-start gap-2 p-3 bg-muted/50 rounded-lg text-xs text-muted-foreground">
<RiExternalLinkLine className="h-4 w-4 shrink-0 mt-0.5" />
<p>
Você será redirecionado para o GitHub Discussions onde poderá
escrever seu feedback. É necessário ter uma conta no GitHub.
</p>
</div>
</DialogContent>
</Dialog>
);
}