eslint migration biome

This commit is contained in:
Marco Pedone 2025-08-28 18:27:07 +02:00
parent 9185d8ddec
commit 3f82763168
348 changed files with 64918 additions and 67612 deletions

View file

@ -17,6 +17,4 @@ knip.json
check-env-vars.js check-env-vars.js
headers headers
.kanelrc.js .kanelrc.js
eslint.config.mjs
prettier.config.cjs
kyselyRules kyselyRules

View file

@ -13,9 +13,4 @@
} }
], ],
"editor.formatOnSave": true, "editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.fixAll.biome": "explicit",
"source.organizeImports.biome": "explicit"
}
} }

View file

@ -44,7 +44,11 @@
"!*compose.yml", "!*compose.yml",
"!.kanelrc.js", "!.kanelrc.js",
"!TODO", "!TODO",
"!*.d.ts" "!*.d.ts",
"!src/i18n/comuni.ts",
"!src/i18n/nazioni.ts",
"!src/i18n/provincie.ts",
"!src/styles/globals.css"
], ],
"ignoreUnknown": true "ignoreUnknown": true
}, },
@ -54,6 +58,7 @@
}, },
"linter": { "linter": {
"enabled": true, "enabled": true,
"domains": { "domains": {
"next": "recommended", "next": "recommended",
"react": "recommended" "react": "recommended"
@ -61,14 +66,29 @@
"rules": { "rules": {
"recommended": true, "recommended": true,
"a11y": { "a11y": {
"noNoninteractiveElementInteractions": "error" "noNoninteractiveElementInteractions": "error",
"useSemanticElements": "off",
"noAutofocus": "off"
}, },
"suspicious": { "suspicious": {
"noArrayIndexKey": "off" "useIterableCallbackReturn": "off",
"noArrayIndexKey": "off",
"noUnknownAtRules": "off"
},
"complexity": {
"noUselessFragments": "off"
}, },
"correctness": { "correctness": {
"useExhaustiveDependencies": "off" "useHookAtTopLevel": "off",
"useExhaustiveDependencies": "off",
"useParseIntRadix": "off"
},
"performance": {
"noImgElement": "off"
},
"security": {
"noDangerouslySetInnerHtml": "off"
} }
} }
}, },

View file

@ -2,13 +2,13 @@ import {
Body, Body,
Container, Container,
Head, Head,
Hr,
Html, Html,
Img,
Preview, Preview,
Section, Section,
Text,
Tailwind, Tailwind,
Img, Text,
Hr,
} from "@react-email/components"; } from "@react-email/components";
import type { JSX } from "react"; import type { JSX } from "react";

View file

@ -20,7 +20,7 @@ const EmailContattoInteressato = ({
sesso, sesso,
}: EmailContattoInteressatoProps) => { }: EmailContattoInteressatoProps) => {
const sig = sesso const sig = sesso
? sesso == "M" ? sesso === "M"
? "Il Sig." ? "Il Sig."
: "La Sig.ra" : "La Sig.ra"
: "Il/La Sig./Sig.ra"; : "Il/La Sig./Sig.ra";
@ -37,7 +37,7 @@ const EmailContattoInteressato = ({
la contatterà {sig} {nome_cognome_utente} (tel: {telefono}), la contatterà {sig} {nome_cognome_utente} (tel: {telefono}),
cliente Arca abbonato tramite il nostro servizio online cliente Arca abbonato tramite il nostro servizio online
Infoalloggi.it interessato a vedere il Suo immobile{" "} Infoalloggi.it interessato a vedere il Suo immobile{" "}
{indirizzo ? "di " + indirizzo : ""}. {indirizzo ? `di ${indirizzo}` : ""}.
</Text> </Text>
<Text className="text-base"> <Text className="text-base">
Per ulteriori informazioni e chiarimenti non esiti a contattarci Per ulteriori informazioni e chiarimenti non esiti a contattarci

View file

@ -1,4 +1,4 @@
import { Heading, Row, Section, Text, Button } from "@react-email/components"; import { Button, Heading, Row, Section, Text } from "@react-email/components";
import Base from "./base"; import Base from "./base";
export type PwResetLink_NewMail = { export type PwResetLink_NewMail = {
mailType: "pwResetLink"; mailType: "pwResetLink";

View file

@ -1,152 +0,0 @@
import react from "eslint-plugin-react";
import typescriptEslint from "@typescript-eslint/eslint-plugin";
import pluginQuery from "@tanstack/eslint-plugin-query";
import kyselyRules from "./kyselyRules/plugin.js";
import tsParser from "@typescript-eslint/parser";
import path from "node:path";
import { fileURLToPath } from "node:url";
import js from "@eslint/js";
import noRelativeImportPaths from "eslint-plugin-no-relative-import-paths";
import { FlatCompat } from "@eslint/eslintrc";
import jsxA11y from "eslint-plugin-jsx-a11y";
import eslintPluginBetterTailwindcss from "eslint-plugin-better-tailwindcss";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
});
export default [
...pluginQuery.configs["flat/recommended"],
{
ignores: [
"**/.next",
"**/out",
"**/public",
"**/node_modules/",
"**/check-env-vars.js",
"**/headers/",
"**/schemas/",
"**/kyselyRules/",
"prettier.config.cjs",
"postcss.config.cjs",
".kanelrc.js",
],
},
...compat.extends(
"eslint:recommended",
"plugin:react/recommended",
"plugin:@next/next/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-type-checked",
"plugin:@typescript-eslint/stylistic-type-checked",
"plugin:jsx-a11y/recommended",
),
{
plugins: {
react,
"@typescript-eslint": typescriptEslint,
"better-tailwindcss": eslintPluginBetterTailwindcss,
"jsx-a11y": jsxA11y,
kyselyRules: kyselyRules,
//"no-relative-import-paths": noRelativeImportPaths,
},
languageOptions: {
parser: tsParser,
ecmaVersion: 5,
sourceType: "script",
parserOptions: {
project: true,
tsconfigRootDir: "./",
},
},
linterOptions: {
reportUnusedDisableDirectives: true,
},
settings: {
react: {
version: "detect",
},
"import/resolver": {
typescript: {
alwaysTryTypes: true,
project: "./tsconfig.json",
},
},
"better-tailwindcss": {
entryPoint: "src/styles/globals.css",
},
},
rules: {
"react/react-in-jsx-scope": "off",
"react-hooks/exhaustive-deps": "off",
"react/prop-types": "off",
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/array-type": "off",
"@typescript-eslint/no-redundant-type-constituents": "warn",
"@typescript-eslint/consistent-type-definitions": "off",
"@typescript-eslint/prefer-optional-chain": "off",
"@typescript-eslint/prefer-nullish-coalescing": "off",
"@typescript-eslint/no-empty-interface": "off",
"@typescript-eslint/unbound-method": "off",
"@typescript-eslint/consistent-type-imports": [
"warn",
{
prefer: "type-imports",
fixStyle: "inline-type-imports",
},
],
"@typescript-eslint/no-unused-vars": [
"warn",
{
argsIgnorePattern: "^_",
},
],
"@typescript-eslint/require-await": "off",
"@typescript-eslint/switch-exhaustiveness-check": "warn",
"@typescript-eslint/no-misused-promises": [
"error",
{
checksVoidReturn: {
attributes: false,
},
},
],
"@next/next/no-img-element": "warn",
"kyselyRules/enforce-select": "error",
"kyselyRules/enforce-where": "error",
"kyselyRules/enforce-null": "error",
...eslintPluginBetterTailwindcss.configs["recommended-warn"]?.rules,
...eslintPluginBetterTailwindcss.configs["recommended-error"]?.rules,
"better-tailwindcss/enforce-consistent-line-wrapping": "off",
"better-tailwindcss/enforce-consistent-class-order": "off",
},
},
{
//ignores: ["**/emails/**/*.tsx", "next.config.js"],
files: ["src/**/*.tsx", "src/**/*.ts"],
plugins: {
"no-relative-import-paths": noRelativeImportPaths,
},
rules: {
"no-relative-import-paths/no-relative-import-paths": [
"warn",
{ rootDir: "src", prefix: "~" },
],
},
},
];

View file

@ -1,14 +1,8 @@
{ {
"$schema": "https://unpkg.com/knip@5/schema.json", "$schema": "https://unpkg.com/knip@5/schema.json",
"project": [ "project": ["src/**", "**", "!src/schemas/public/*.ts", "!emails/**"],
"src/**",
"**",
"!src/schemas/public/*.ts",
"!emails/**"
],
"ignore": [ "ignore": [
".kanelrc.js", ".kanelrc.js",
".eslintrc.json",
"TypeHelpers.type.ts", "TypeHelpers.type.ts",
"src/utils/api.ts", "src/utils/api.ts",
"src/server/api/trpc.ts", "src/server/api/trpc.ts",
@ -23,26 +17,15 @@
"src/utils/get-media-url.ts", "src/utils/get-media-url.ts",
"src/utils/utils.ts" "src/utils/utils.ts"
], ],
"ignoreBinaries": [ "ignoreBinaries": ["stripe"],
"stripe"
],
"ignoreDependencies": [ "ignoreDependencies": [
"kysely-plugin-serialize", "kysely-plugin-serialize",
"sharp", "sharp",
"uuid", "uuid",
"@react-email/components", "@react-email/components",
"@eslint/compat",
"@next/eslint-plugin-next",
"@prettier/sync",
"@types/eslint",
"@types/uuid", "@types/uuid",
"eslint-config-next",
"eslint-import-resolver-typescript",
"eslint-plugin-import",
"eslint-plugin-react-hooks",
"kanel-kysely", "kanel-kysely",
"npm-run-all", "npm-run-all",
"typescript-eslint",
"@react-email/preview-server", "@react-email/preview-server",
"@tailwindcss/forms", "@tailwindcss/forms",
"@tailwindcss/typography", "@tailwindcss/typography",

View file

@ -34,9 +34,7 @@ const nextConfig = {
typescript: { typescript: {
ignoreBuildErrors: true, ignoreBuildErrors: true,
}, },
eslint: {
ignoreDuringBuilds: true,
},
devIndicators: false, devIndicators: false,
rewrites: async () => { rewrites: async () => {
return [ return [
@ -46,11 +44,11 @@ const nextConfig = {
}, },
{ {
source: "/go-api/images/get/:slug*", source: "/go-api/images/get/:slug*",
destination: env.BACKENDSERVER_URL + "/images/get/:slug*", destination: `${env.BACKENDSERVER_URL}/images/get/:slug*`,
}, },
{ {
source: "/go-api/storage/get/:slug*", source: "/go-api/storage/get/:slug*",
destination: env.BACKENDSERVER_URL + "/storage/get/:slug*", destination: `${env.BACKENDSERVER_URL}/storage/get/:slug*`,
has: [ has: [
{ type: "cookie", key: "access_token" }, { type: "cookie", key: "access_token" },
{ {
@ -63,7 +61,7 @@ const nextConfig = {
}, },
{ {
source: "/go-api/storage/upload:slug*", source: "/go-api/storage/upload:slug*",
destination: env.BACKENDSERVER_URL + "/storage/upload:slug*", destination: `${env.BACKENDSERVER_URL}/storage/upload:slug*`,
has: [ has: [
{ type: "cookie", key: "access_token" }, { type: "cookie", key: "access_token" },
{ {

File diff suppressed because it is too large Load diff

View file

@ -101,17 +101,9 @@
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "2.2.2", "@biomejs/biome": "2.2.2",
"@eslint/compat": "^1.3.1",
"@eslint/eslintrc": "^3.3.0",
"@eslint/js": "^9.32.0",
"@hookform/devtools": "^4.4.0", "@hookform/devtools": "^4.4.0",
"@next/eslint-plugin-next": "^15.4.5",
"@prettier/sync": "^0.6.1",
"@react-email/preview-server": "^4.2.8", "@react-email/preview-server": "^4.2.8",
"@tanstack/eslint-plugin-query": "^5.83.1",
"@total-typescript/ts-reset": "^0.6.1", "@total-typescript/ts-reset": "^0.6.1",
"@types/eslint": "^9.6.1",
"@types/eslint-plugin-jsx-a11y": "^6.10.0",
"@types/js-cookie": "^3.0.6", "@types/js-cookie": "^3.0.6",
"@types/leaflet": "^1.9.20", "@types/leaflet": "^1.9.20",
"@types/node": "^24.2.0", "@types/node": "^24.2.0",
@ -122,27 +114,13 @@
"@types/react-dom": "^19.1.7", "@types/react-dom": "^19.1.7",
"@types/react-is": "^19.0.0", "@types/react-is": "^19.0.0",
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"@typescript-eslint/eslint-plugin": "^8.39.0",
"@typescript-eslint/parser": "^8.39.0",
"cross-env": "^10.0.0", "cross-env": "^10.0.0",
"eslint": "^9.32.0",
"eslint-config-next": "^15.4.5",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-better-tailwindcss": "^3.7.4",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-no-relative-import-paths": "^1.6.1",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.2.0",
"jiti": "^2.5.1", "jiti": "^2.5.1",
"kanel": "^3.14.2", "kanel": "^3.14.2",
"kanel-kysely": "^0.7.1", "kanel-kysely": "^0.7.1",
"knip": "^5.62.0", "knip": "^5.62.0",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"prettier": "^3.6.2", "typescript": "^5.9.2"
"prettier-plugin-classnames": "^0.8.2",
"prettier-plugin-tailwindcss": "^0.6.14",
"typescript": "^5.9.2",
"typescript-eslint": "^8.39.0"
}, },
"ct3aMetadata": { "ct3aMetadata": {
"initVersion": "7.9.0" "initVersion": "7.9.0"

View file

@ -1,4 +1,4 @@
/* eslint-env node */
const config = { const config = {
plugins: { plugins: {

View file

@ -1,10 +0,0 @@
/* eslint-env node */
/** @type {import("prettier").Config & import('prettier-plugin-tailwindcss').PluginOptions} */
const config = {
printWidth: 80,
plugins: ["prettier-plugin-classnames", "prettier-plugin-tailwindcss"],
customAttributes: ["className"],
customFunctions: ["classNames"],
};
module.exports = config;

View file

@ -1,6 +1,6 @@
import { Suspense } from "react"; import { Suspense } from "react";
import Annunci from "~/_app/ui/annunci";
import { getDataFromDB } from "~/_app/lib/annunci"; import { getDataFromDB } from "~/_app/lib/annunci";
import AnnunciList from "~/_app/ui/annunci";
import { LoadingPage } from "~/components/loading"; import { LoadingPage } from "~/components/loading";
export default function TestAppPage() { export default function TestAppPage() {
@ -14,7 +14,7 @@ export default function TestAppPage() {
<h2 className="mb-2 text-lg font-semibold">Data from Database:</h2> <h2 className="mb-2 text-lg font-semibold">Data from Database:</h2>
<Suspense fallback={<LoadingPage />}> <Suspense fallback={<LoadingPage />}>
<Annunci annunci={annunci} /> <AnnunciList annunci={annunci} />
</Suspense> </Suspense>
</div> </div>
</div> </div>

View file

@ -6,7 +6,7 @@ type AnnunciProps = {
annunci: Promise<Pick<Annunci, "codice">[]>; annunci: Promise<Pick<Annunci, "codice">[]>;
}; };
export default function Annunci({ annunci }: AnnunciProps) { export default function AnnunciList({ annunci }: AnnunciProps) {
const allAnnunci = use(annunci); const allAnnunci = use(annunci);
return ( return (

View file

@ -23,6 +23,7 @@ import {
House, House,
Info, Info,
LayoutDashboard, LayoutDashboard,
type LucideProps,
Mail, Mail,
MessageSquareText, MessageSquareText,
MessagesSquare, MessagesSquare,
@ -42,20 +43,19 @@ import {
User, User,
Users, Users,
Wifi, Wifi,
type LucideProps,
} from "lucide-react"; } from "lucide-react";
import type {
ComponentPropsWithoutRef,
ForwardRefExoticComponent,
RefAttributes,
} from "react";
import toast from "react-hot-toast";
import { import {
Tooltip, Tooltip,
TooltipContent, TooltipContent,
TooltipProvider, TooltipProvider,
TooltipTrigger, TooltipTrigger,
} from "~/components/ui/tooltip"; } from "~/components/ui/tooltip";
import toast from "react-hot-toast";
import type {
ComponentPropsWithoutRef,
ForwardRefExoticComponent,
RefAttributes,
} from "react";
const iconOptions = [ const iconOptions = [
"heater", "heater",
@ -315,6 +315,7 @@ export const ShieldExclamationIcon = ({
fill="currentColor" fill="currentColor"
className={className} className={className}
> >
<title>Shield</title>
<path <path
fillRule="evenodd" fillRule="evenodd"
d="M11.484 2.17a.75.75 0 0 1 1.032 0 11.209 11.209 0 0 0 7.877 3.08.75.75 0 0 1 .722.515 12.74 12.74 0 0 1 .635 3.985c0 5.942-4.064 10.933-9.563 12.348a.749.749 0 0 1-.374 0C6.314 20.683 2.25 15.692 2.25 9.75c0-1.39.223-2.73.635-3.985a.75.75 0 0 1 .722-.516l.143.001c2.996 0 5.718-1.17 7.734-3.08ZM12 8.25a.75.75 0 0 1 .75.75v3.75a.75.75 0 0 1-1.5 0V9a.75.75 0 0 1 .75-.75ZM12 15a.75.75 0 0 0-.75.75v.008c0 .414.336.75.75.75h.008a.75.75 0 0 0 .75-.75v-.008a.75.75 0 0 0-.75-.75H12Z" d="M11.484 2.17a.75.75 0 0 1 1.032 0 11.209 11.209 0 0 0 7.877 3.08.75.75 0 0 1 .722.515 12.74 12.74 0 0 1 .635 3.985c0 5.942-4.064 10.933-9.563 12.348a.749.749 0 0 1-.374 0C6.314 20.683 2.25 15.692 2.25 9.75c0-1.39.223-2.73.635-3.985a.75.75 0 0 1 .722-.516l.143.001c2.996 0 5.718-1.17 7.734-3.08ZM12 8.25a.75.75 0 0 1 .75.75v3.75a.75.75 0 0 1-1.5 0V9a.75.75 0 0 1 .75-.75ZM12 15a.75.75 0 0 0-.75.75v.008c0 .414.336.75.75.75h.008a.75.75 0 0 0 .75-.75v-.008a.75.75 0 0 0-.75-.75H12Z"
@ -334,6 +335,7 @@ export const QuestionMarkCircleIcon = ({
fill="currentColor" fill="currentColor"
className={className} className={className}
> >
<title>QuestionMark</title>
<path <path
fillRule="evenodd" fillRule="evenodd"
d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm11.378-3.917c-.89-.777-2.366-.777-3.255 0a.75.75 0 0 1-.988-1.129c1.454-1.272 3.776-1.272 5.23 0 1.513 1.324 1.513 3.518 0 4.842a3.75 3.75 0 0 1-.837.552c-.676.328-1.028.774-1.028 1.152v.75a.75.75 0 0 1-1.5 0v-.75c0-1.279 1.06-2.107 1.875-2.502.182-.088.351-.199.503-.331.83-.727.83-1.857 0-2.584ZM12 18a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Z" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm11.378-3.917c-.89-.777-2.366-.777-3.255 0a.75.75 0 0 1-.988-1.129c1.454-1.272 3.776-1.272 5.23 0 1.513 1.324 1.513 3.518 0 4.842a3.75 3.75 0 0 1-.837.552c-.676.328-1.028.774-1.028 1.152v.75a.75.75 0 0 1-1.5 0v-.75c0-1.279 1.06-2.107 1.875-2.502.182-.088.351-.199.503-.331.83-.727.83-1.857 0-2.584ZM12 18a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Z"
@ -351,6 +353,7 @@ export const HomeIcon = ({ className }: { className?: string }) => (
stroke="currentColor" stroke="currentColor"
className={className} className={className}
> >
<title>Home</title>
<path <path
strokeLinecap="round" strokeLinecap="round"
strokeLinejoin="round" strokeLinejoin="round"
@ -365,6 +368,7 @@ const CheckCircleIcon = ({ className }: { className?: string }) => (
fill="currentColor" fill="currentColor"
className={className} className={className}
> >
<title>CheckCircle</title>
<path <path
fillRule="evenodd" fillRule="evenodd"
d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094l3.75-5.25Z" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094l3.75-5.25Z"

View file

@ -1,5 +1,5 @@
import Image from "next/image"; import Image from "next/image";
import { type ComponentProps } from "react"; import type { ComponentProps } from "react";
const fallbackImage = "/fallback-image.png"; const fallbackImage = "/fallback-image.png";
export const ImageFlbk = (props: ComponentProps<typeof Image>) => { export const ImageFlbk = (props: ComponentProps<typeof Image>) => {

View file

@ -1,14 +1,15 @@
import { cn } from "~/lib/utils"; import { ExternalLink } from "lucide-react";
import Link from "next/link";
import type { ReactNode } from "react";
import { import {
HybridTooltip, HybridTooltip,
HybridTooltipContent, HybridTooltipContent,
HybridTooltipTrigger, HybridTooltipTrigger,
} from "~/components/custom_ui/HybridTooltip"; } from "~/components/custom_ui/HybridTooltip";
import { TooltipProvider } from "~/components/ui/tooltip";
import { IconMatrix, type IconType } from "~/components/IconComponents"; import { IconMatrix, type IconType } from "~/components/IconComponents";
import Link from "next/link"; import { TooltipProvider } from "~/components/ui/tooltip";
import { ExternalLink } from "lucide-react"; import { cn } from "~/lib/utils";
import type { ReactNode } from "react";
/* /*
<TouchProvider> <TouchProvider>
<div className="relative"> <div className="relative">

View file

@ -1,11 +1,3 @@
import { useContext, type ReactNode } from "react";
import { BannerFactory } from "~/components/banners";
import { Footer, MiniFooter } from "~/components/footer";
import { SiteHeader } from "~/components/navbar/site-header";
import { useTranslation } from "~/providers/I18nProvider";
import { UserViewContext, UserViewProvider } from "~/lib/userViewContext";
import Head from "next/head";
import Link from "next/link";
import { import {
ExternalLink, ExternalLink,
Mail, Mail,
@ -16,21 +8,29 @@ import {
Tickets, Tickets,
UserCog, UserCog,
} from "lucide-react"; } from "lucide-react";
import Head from "next/head";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useRouter } from "next/router";
import { type ReactNode, useContext } from "react";
import toast from "react-hot-toast";
import { Sidebar } from "~/components/area-riservata/sidebar";
import { BannerFactory } from "~/components/banners";
import { Footer, MiniFooter } from "~/components/footer";
import { LoadingPage } from "~/components/loading";
import { SiteHeader } from "~/components/navbar/site-header";
import { WhatsAppIcon } from "~/components/svgs";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { Separator } from "~/components/ui/separator"; import { Separator } from "~/components/ui/separator";
import { usePathname } from "next/navigation"; import { UserViewContext, UserViewProvider } from "~/lib/userViewContext";
import { api } from "~/utils/api"; import { useTranslation } from "~/providers/I18nProvider";
import { Sidebar } from "~/components/area-riservata/sidebar";
import type { UsersId } from "~/schemas/public/Users";
import toast from "react-hot-toast";
import { useRouter } from "next/router";
import { import {
useSession,
EnforcedSessionContext, EnforcedSessionContext,
useSession,
} from "~/providers/SessionProvider"; } from "~/providers/SessionProvider";
import { WhatsAppIcon } from "~/components/svgs"; import type { UsersId } from "~/schemas/public/Users";
import { LoadingPage } from "~/components/loading";
import type { ValidSession } from "~/server/api/trpc"; import type { ValidSession } from "~/server/api/trpc";
import { api } from "~/utils/api";
interface Props { interface Props {
children: ReactNode; children: ReactNode;
@ -80,7 +80,7 @@ export const AreaRiservataLayout = ({
<main className="flex h-full flex-1 overflow-auto"> <main className="flex h-full flex-1 overflow-auto">
<div className="flex h-auto w-full flex-col md:flex-row"> <div className="flex h-auto w-full flex-col md:flex-row">
<LoadingPage />; <LoadingPage />
</div> </div>
</main> </main>
{!noFooter && <MiniFooter />} {!noFooter && <MiniFooter />}
@ -94,7 +94,7 @@ export const AreaRiservataLayout = ({
<main className="flex h-full flex-1 overflow-auto"> <main className="flex h-full flex-1 overflow-auto">
<div className="flex h-auto w-full flex-col md:flex-row"> <div className="flex h-auto w-full flex-col md:flex-row">
<LoadingPage />; <LoadingPage />
</div> </div>
</main> </main>
{!noFooter && <MiniFooter />} {!noFooter && <MiniFooter />}

View file

@ -1,8 +1,8 @@
"use client"; "use client";
import dynamic from "next/dynamic";
import { Button } from "~/components/ui/button";
import { MapIcon } from "lucide-react"; import { MapIcon } from "lucide-react";
import { useTranslation } from "~/providers/I18nProvider"; import dynamic from "next/dynamic";
import { useState } from "react";
import { Button } from "~/components/ui/button";
import { import {
Dialog, Dialog,
DialogContent, DialogContent,
@ -11,9 +11,9 @@ import {
DialogTitle, DialogTitle,
DialogTrigger, DialogTrigger,
} from "~/components/ui/dialog"; } from "~/components/ui/dialog";
import { useState } from "react"; import { useTranslation } from "~/providers/I18nProvider";
const Map = dynamic(() => import("~/components/map/Map"), { const MapComp = dynamic(() => import("~/components/map/Map"), {
ssr: false, ssr: false,
}); });
@ -41,7 +41,7 @@ export const MappaDialogFullscreen = ({
<div className="size-full"> <div className="size-full">
{lat && long && ( {lat && long && (
<> <>
<Map <MapComp
posix={{ posix={{
pos: { pos: {
lat: Number.parseFloat(lat), lat: Number.parseFloat(lat),

View file

@ -1,25 +1,25 @@
"use client"; "use client";
import { api } from "~/utils/api";
import { useState, type FormEvent } from "react";
import { import {
Elements, Elements,
PaymentElement, PaymentElement,
useElements, useElements,
useStripe, useStripe,
} from "@stripe/react-stripe-js"; } from "@stripe/react-stripe-js";
import type { Stripe } from "@stripe/stripe-js";
import { ArrowRight, ExternalLink } from "lucide-react";
import Link from "next/link";
import { type FormEvent, useState } from "react";
import LoadingButton from "~/components/custom_ui/loading-button";
import { LoadingPage } from "~/components/loading"; import { LoadingPage } from "~/components/loading";
import { Status500 } from "~/components/status-page"; import { Status500 } from "~/components/status-page";
import LoadingButton from "~/components/custom_ui/loading-button";
import { useTranslation } from "~/providers/I18nProvider";
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
import type { Stripe } from "@stripe/stripe-js";
import { formatCurrency } from "~/lib/utils";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
import { env } from "~/env.mjs";
import { formatCurrency } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider";
import type { PaymentsId } from "~/schemas/public/Payments"; import type { PaymentsId } from "~/schemas/public/Payments";
import type { PrezziarioIdprezziario } from "~/schemas/public/Prezziario"; import type { PrezziarioIdprezziario } from "~/schemas/public/Prezziario";
import { ArrowRight, ExternalLink } from "lucide-react"; import { api } from "~/utils/api";
import { env } from "~/env.mjs";
import Link from "next/link";
type AcquistoProcessingProps = { type AcquistoProcessingProps = {
paymentId: PaymentsId; paymentId: PaymentsId;
@ -69,8 +69,7 @@ export const AcquistoProcessing = ({
) : isPending ? ( ) : isPending ? (
<LoadingPage /> <LoadingPage />
) : ( ) : (
stripeIntent && stripeIntent?.clientSecret && (
stripeIntent.clientSecret && (
<> <>
<Elements <Elements
options={{ options={{

View file

@ -1,14 +1,14 @@
"use client"; "use client";
import { format } from "date-fns";
import { it } from "date-fns/locale";
import Image from "next/image";
import { useRef } from "react";
import { useReactToPrint } from "react-to-print";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { Card } from "~/components/ui/card"; import { Card } from "~/components/ui/card";
import Image from "next/image";
import { format } from "date-fns";
import { useReactToPrint } from "react-to-print";
import { it } from "date-fns/locale";
import { formatCurrency } from "~/lib/utils";
import { useRef } from "react";
import { PaymentMethodToString, type PaymentType } from "~/i18n/stripe"; import { PaymentMethodToString, type PaymentType } from "~/i18n/stripe";
import { formatCurrency } from "~/lib/utils";
export function ReceiptGenerator({ data }: { data: PurchaseData }) { export function ReceiptGenerator({ data }: { data: PurchaseData }) {
const contentRef = useRef<HTMLDivElement>(null); const contentRef = useRef<HTMLDivElement>(null);

View file

@ -1,8 +1,8 @@
import { useEffect, useRef, useState } from "react";
import { LoadingPage } from "~/components/loading";
import { cn } from "~/lib/utils"; import { cn } from "~/lib/utils";
import type { TempTokensToken } from "~/schemas/public/TempTokens"; import type { TempTokensToken } from "~/schemas/public/TempTokens";
import { api } from "~/utils/api"; import { api } from "~/utils/api";
import { LoadingPage } from "~/components/loading";
import { useEffect, useRef, useState } from "react";
export const AllegatoIframe = ({ export const AllegatoIframe = ({
className, className,
@ -15,7 +15,7 @@ export const AllegatoIframe = ({
const { mutateAsync: getToken } = api.storage.getStorageToken.useMutation(); const { mutateAsync: getToken } = api.storage.getStorageToken.useMutation();
const [token, setToken] = useState<TempTokensToken | null>(null); const [token, setToken] = useState<TempTokensToken | null>(null);
const handleIframeLoad = () => { const handleIframeLoad = () => {
if (if_ref.current && if_ref.current.contentWindow) { if (if_ref.current?.contentWindow) {
const img = if_ref.current.contentWindow.document.querySelector("img"); const img = if_ref.current.contentWindow.document.querySelector("img");
if (img) { if (img) {
img.style.width = "100%"; img.style.width = "100%";
@ -43,6 +43,7 @@ export const AllegatoIframe = ({
className, className,
)} )}
> >
{/** biome-ignore lint/a11y/noNoninteractiveElementInteractions: <need interaction> */}
<iframe <iframe
title="Allegato" title="Allegato"
ref={if_ref} ref={if_ref}

View file

@ -1,5 +1,5 @@
import { getTitoloTranslation } from "~/lib/annuncio_details";
import { CardAnnuncio } from "~/components/annuncio_card"; import { CardAnnuncio } from "~/components/annuncio_card";
import { getTitoloTranslation } from "~/lib/annuncio_details";
import { useTranslation } from "~/providers/I18nProvider"; import { useTranslation } from "~/providers/I18nProvider";
import type { AnnuncioRicerca } from "~/server/controllers/annunci.controller"; import type { AnnuncioRicerca } from "~/server/controllers/annunci.controller";

View file

@ -1,23 +1,23 @@
import dynamic from "next/dynamic";
import type { AnnuncioRicercaWPosition } from "~/server/controllers/annunci.controller";
import { api } from "~/utils/api";
import { LoadingPage } from "~/components/loading";
import { Status500 } from "~/components/status-page";
import { useTranslation } from "~/providers/I18nProvider";
import { AnimatePresence, motion } from "framer-motion"; import { AnimatePresence, motion } from "framer-motion";
import dynamic from "next/dynamic";
import Image from "next/image"; import Image from "next/image";
import { formatCurrency } from "~/lib/utils";
import { handleConsegna } from "~/lib/annuncio_details";
import { import {
type Dispatch,
Fragment, Fragment,
memo, memo,
useState,
type Dispatch,
type SetStateAction, type SetStateAction,
useState,
} from "react"; } from "react";
import { LoadingPage } from "~/components/loading";
import { Status500 } from "~/components/status-page";
import { handleConsegna } from "~/lib/annuncio_details";
import { formatCurrency } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider";
import { useRicerca } from "~/providers/RicercaProvider"; import { useRicerca } from "~/providers/RicercaProvider";
import type { AnnuncioRicercaWPosition } from "~/server/controllers/annunci.controller";
import { api } from "~/utils/api";
const Map = dynamic(() => import("~/components/map/Map"), { const MapComp = dynamic(() => import("~/components/map/Map"), {
ssr: false, ssr: false,
}); });
@ -78,7 +78,7 @@ const MapDisplay = memo(
.filter((a) => a !== undefined); .filter((a) => a !== undefined);
return ( return (
<Map <MapComp
isGroup isGroup
groupData={posizioni} groupData={posizioni}
posix={{ pos: { lat: 45.764718, lng: 11.73067 } }} posix={{ pos: { lat: 45.764718, lng: 11.73067 } }}
@ -118,7 +118,7 @@ const SelectedComp = memo(
key={selected.id} key={selected.id}
> >
<div className="flex gap-2"> <div className="flex gap-2">
{selected.url_immagini && selected.url_immagini[0] ? ( {selected.url_immagini?.[0] ? (
<Image <Image
src={selected.url_immagini[0]} src={selected.url_immagini[0]}
width={500} width={500}

View file

@ -1,8 +1,11 @@
"use client"; "use client";
import { DialogTrigger } from "@radix-ui/react-dialog";
import { getCookie, setCookie } from "cookies-next/client"; import { getCookie, setCookie } from "cookies-next/client";
import { add } from "date-fns"; import { add } from "date-fns";
import { ArrowRight, CircleHelp } from "lucide-react";
import { useRouter } from "next/router";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { Button } from "~/components/ui/button";
import { import {
Dialog, Dialog,
DialogContent, DialogContent,
@ -10,10 +13,6 @@ import {
DialogHeader, DialogHeader,
DialogTitle, DialogTitle,
} from "~/components/ui/dialog"; } from "~/components/ui/dialog";
import { Button } from "~/components/ui/button";
import { useRouter } from "next/router";
import { ArrowRight, CircleHelp } from "lucide-react";
import { DialogTrigger } from "@radix-ui/react-dialog";
import { useTranslation } from "~/providers/I18nProvider"; import { useTranslation } from "~/providers/I18nProvider";
const COOKIE_KEY = "tipologia_tutorial_shown"; const COOKIE_KEY = "tipologia_tutorial_shown";
@ -28,7 +27,7 @@ export const CTA_TipologiaModal = () => {
expires: add(new Date(), { days: 30 }), // Set cookie to expire in 30 days expires: add(new Date(), { days: 30 }), // Set cookie to expire in 30 days
}); });
if (v !== null) { if (v !== null) {
window.location.assign("/annunci?tipo=" + v); window.location.assign(`/annunci?tipo=${v}`);
} }
setOpen(false); setOpen(false);
}; };
@ -36,7 +35,7 @@ export const CTA_TipologiaModal = () => {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
useEffect(() => { useEffect(() => {
if (path == "/annunci" && !hasCookie) { if (path === "/annunci" && !hasCookie) {
const timer = setTimeout(() => { const timer = setTimeout(() => {
setOpen(true); setOpen(true);
}, 1000); // 1 second delay }, 1000); // 1 second delay

View file

@ -1,16 +1,16 @@
import { ArrowRight, BadgePlus, LogIn } from "lucide-react"; import { ArrowRight, BadgePlus, LogIn } from "lucide-react";
import { cn } from "~/lib/utils";
import { Button, buttonVariants } from "~/components/ui/button";
import { useRouter } from "next/router";
import { api } from "~/utils/api";
import Link from "next/link"; import Link from "next/link";
import { useRouter } from "next/router";
import toast from "react-hot-toast";
import { ContattoAnnuncio } from "~/components/annuncio-interactions/contatto_modal";
import LoadingButton from "~/components/custom_ui/loading-button";
import { Button, buttonVariants } from "~/components/ui/button";
import { cn } from "~/lib/utils";
import { useAnnuncio } from "~/providers/AnnuncioProvider"; import { useAnnuncio } from "~/providers/AnnuncioProvider";
import type { SessionContextType } from "~/providers/SessionProvider"; import type { SessionContextType } from "~/providers/SessionProvider";
import LoadingButton from "~/components/custom_ui/loading-button";
import type { UsersId } from "~/schemas/public/Users";
import type { AnnunciId } from "~/schemas/public/Annunci"; import type { AnnunciId } from "~/schemas/public/Annunci";
import { ContattoAnnuncio } from "~/components/annuncio-interactions/contatto_modal"; import type { UsersId } from "~/schemas/public/Users";
import toast from "react-hot-toast"; import { api } from "~/utils/api";
export const AnnuncioInteractions = ({ export const AnnuncioInteractions = ({
session, session,
@ -79,9 +79,9 @@ const ServizioInteraction = ({
if (isLoading) return <LoadingButton loading className="w-full" />; if (isLoading) return <LoadingButton loading className="w-full" />;
if ( if (
servizio == undefined || servizio === undefined ||
servizio.status == "invalid" || servizio.status === "invalid" ||
servizio.status == "not_found" servizio.status === "not_found"
) { ) {
return ( return (
<div> <div>
@ -90,7 +90,7 @@ const ServizioInteraction = ({
); );
} }
if (servizio.status == "already_saved") { if (servizio.status === "already_saved") {
return ( return (
<div className="flex w-full flex-col gap-2"> <div className="flex w-full flex-col gap-2">
<div className="w-full text-center font-semibold text-green-500"> <div className="w-full text-center font-semibold text-green-500">

View file

@ -1,4 +1,4 @@
import { useAnnuncio } from "~/providers/AnnuncioProvider"; import { MessageCircleQuestion } from "lucide-react";
import { import {
Credenza, Credenza,
CredenzaBody, CredenzaBody,
@ -8,9 +8,9 @@ import {
CredenzaTitle, CredenzaTitle,
CredenzaTrigger, CredenzaTrigger,
} from "~/components/custom_ui/credenza"; } from "~/components/custom_ui/credenza";
import { FormContattoAnnucio } from "~/forms/FormContattoAnnuncio";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { MessageCircleQuestion } from "lucide-react"; import { FormContattoAnnucio } from "~/forms/FormContattoAnnuncio";
import { useAnnuncio } from "~/providers/AnnuncioProvider";
export const ContattoAnnuncio = () => { export const ContattoAnnuncio = () => {
const { codice } = useAnnuncio(); const { codice } = useAnnuncio();

View file

@ -1,4 +1,8 @@
import { BedDouble, CalendarClock, Maximize2, Ruler } from "lucide-react";
import Image from "next/image";
import Link from "next/link"; import Link from "next/link";
import { useState } from "react";
import { ImageFlbk } from "~/components/ImageWithFallback";
import { import {
Carousel, Carousel,
CarouselContent, CarouselContent,
@ -6,11 +10,6 @@ import {
CarouselNext, CarouselNext,
CarouselPrevious, CarouselPrevious,
} from "~/components/ui/carousel"; } from "~/components/ui/carousel";
import { cn, formatCurrency } from "~/lib/utils";
import { BedDouble, CalendarClock, Maximize2, Ruler } from "lucide-react";
import Image from "next/image";
import { useTranslation } from "~/providers/I18nProvider";
import { useState } from "react";
import { import {
Dialog, Dialog,
DialogContent, DialogContent,
@ -19,7 +18,8 @@ import {
DialogTitle, DialogTitle,
} from "~/components/ui/dialog"; } from "~/components/ui/dialog";
import { camereTesti, handleConsegna } from "~/lib/annuncio_details"; import { camereTesti, handleConsegna } from "~/lib/annuncio_details";
import { ImageFlbk } from "~/components/ImageWithFallback"; import { cn, formatCurrency } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider";
type CardAnnuncioProps = { type CardAnnuncioProps = {
id: number; id: number;
@ -68,7 +68,7 @@ export const CardAnnuncio = ({
className="block p-2" //duration-700 ease-in-out animate-in fade-in className="block p-2" //duration-700 ease-in-out animate-in fade-in
> >
<div className="group relative rounded-xl text-clip"> <div className="group relative rounded-xl text-clip">
{stato == "Trattativa" && ( {stato === "Trattativa" && (
<div> <div>
<div className="absolute z-20 h-56 w-full"> <div className="absolute z-20 h-56 w-full">
<div className="absolute bottom-0 w-full touch-none bg-violet-500 text-center text-lg text-white select-none"> <div className="absolute bottom-0 w-full touch-none bg-violet-500 text-center text-lg text-white select-none">
@ -80,8 +80,7 @@ export const CardAnnuncio = ({
<Carousel opts={{ loop: true }}> <Carousel opts={{ loop: true }}>
<CarouselContent> <CarouselContent>
{immagini && {immagini?.map((img, idx) => (
immagini.map((img, idx) => (
<CarouselItem key={`${img}-${idx}`}> <CarouselItem key={`${img}-${idx}`}>
<ImageFlbk <ImageFlbk
alt={t.card.alt_immagine} alt={t.card.alt_immagine}
@ -223,8 +222,7 @@ export const CarouselAnnuncio = ({
<div className="relative"> <div className="relative">
<Carousel opts={{ loop: true, align: "start" }}> <Carousel opts={{ loop: true, align: "start" }}>
<CarouselContent> <CarouselContent>
{immagini && {immagini?.map((img, idx) => (
immagini.map((img, idx) => (
<CarouselItem <CarouselItem
key={`${img}-${idx}-cF`} key={`${img}-${idx}-cF`}
className={cn( className={cn(
@ -275,8 +273,7 @@ export const CarouselAnnuncio = ({
</DialogHeader> </DialogHeader>
<Carousel opts={{ loop: true, startIndex: idxModal }}> <Carousel opts={{ loop: true, startIndex: idxModal }}>
<CarouselContent> <CarouselContent>
{immagini && {immagini?.map((img, idx) => (
immagini.map((img, idx) => (
<CarouselItem key={`${img}-${idx}-cD`}> <CarouselItem key={`${img}-${idx}-cD`}>
<Image <Image
alt={`carousel-img-${idx}`} alt={`carousel-img-${idx}`}

View file

@ -1,16 +1,4 @@
import toast from "react-hot-toast"; import { format } from "date-fns";
import type {
Storageindex,
StorageindexId,
} from "~/schemas/public/Storageindex";
import type { UsersId } from "~/schemas/public/Users";
import { api } from "~/utils/api";
import { LoadingPage } from "~/components/loading";
import { Status500 } from "~/components/status-page";
import { Separator } from "~/components/ui/separator";
import Link from "next/link";
import { cn } from "~/lib/utils";
import { Button } from "~/components/ui/button";
import { import {
Download, Download,
File, File,
@ -26,9 +14,13 @@ import {
Trash2, Trash2,
TriangleAlert, TriangleAlert,
} from "lucide-react"; } from "lucide-react";
import { useState, type FormEvent } from "react"; import Link from "next/link";
import { useTranslation } from "~/providers/I18nProvider"; import { type FormEvent, useState } from "react";
import toast from "react-hot-toast";
import Input from "~/components/custom_ui/input"; import Input from "~/components/custom_ui/input";
import { LoadingPage } from "~/components/loading";
import { Status500 } from "~/components/status-page";
import { Button } from "~/components/ui/button";
import { import {
Dialog, Dialog,
DialogContent, DialogContent,
@ -36,15 +28,23 @@ import {
DialogHeader, DialogHeader,
DialogTitle, DialogTitle,
} from "~/components/ui/dialog"; } from "~/components/ui/dialog";
import { handleDownload } from "~/hooks/filesHooks";
import { UploadModal } from "~/components/upload_modal";
import { format } from "date-fns";
import { import {
DropdownMenu, DropdownMenu,
DropdownMenuContent, DropdownMenuContent,
DropdownMenuItem, DropdownMenuItem,
DropdownMenuTrigger, DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu"; } from "~/components/ui/dropdown-menu";
import { Separator } from "~/components/ui/separator";
import { UploadModal } from "~/components/upload_modal";
import { handleDownload } from "~/hooks/filesHooks";
import { cn } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider";
import type {
Storageindex,
StorageindexId,
} from "~/schemas/public/Storageindex";
import type { UsersId } from "~/schemas/public/Users";
import { api } from "~/utils/api";
export const AllegatiComp = ({ export const AllegatiComp = ({
userId, userId,

View file

@ -1,5 +1,4 @@
import type { UsersId } from "~/schemas/public/Users"; import { useState } from "react";
import { api } from "~/utils/api";
import { import {
Accordion, Accordion,
AccordionContent, AccordionContent,
@ -7,7 +6,8 @@ import {
AccordionTrigger, AccordionTrigger,
} from "~/components/ui/accordion"; } from "~/components/ui/accordion";
import { useMediaQuery } from "~/hooks/use-media-query"; import { useMediaQuery } from "~/hooks/use-media-query";
import { useState } from "react"; import type { UsersId } from "~/schemas/public/Users";
import { api } from "~/utils/api";
export const EmailAccordion = ({ userId }: { userId: UsersId }) => { export const EmailAccordion = ({ userId }: { userId: UsersId }) => {
const { data } = api.comunicazioni.getEmails.useQuery({ const { data } = api.comunicazioni.getEmails.useQuery({

View file

@ -1,9 +1,8 @@
import { api } from "~/utils/api";
import { LoadingPage } from "~/components/loading";
import type { UsersId } from "~/schemas/public/Users";
import { AccordionComp } from "~/components/accordionComp"; import { AccordionComp } from "~/components/accordionComp";
import { useTranslation } from "~/providers/I18nProvider"; import { LoadingPage } from "~/components/loading";
import { TabRicerca } from "~/components/tables/ricerca-table";
import TimeserieBarChart from "~/components/timeserieBarChart"; import TimeserieBarChart from "~/components/timeserieBarChart";
import TimeserieBarChartStacked from "~/components/timeserieBarChartStacked";
import { import {
Card, Card,
CardContent, CardContent,
@ -11,8 +10,9 @@ import {
CardHeader, CardHeader,
CardTitle, CardTitle,
} from "~/components/ui/card"; } from "~/components/ui/card";
import TimeserieBarChartStacked from "~/components/timeserieBarChartStacked"; import { useTranslation } from "~/providers/I18nProvider";
import { TabRicerca } from "~/components/tables/ricerca-table"; import type { UsersId } from "~/schemas/public/Users";
import { api } from "~/utils/api";
export const AdminDashboard = () => { export const AdminDashboard = () => {
const { data: stats, isLoading } = api.stats.adminDashStats.useQuery(); const { data: stats, isLoading } = api.stats.adminDashStats.useQuery();

View file

@ -1,22 +1,19 @@
import { CircleCheck, CircleSlash, ReceiptText, Trash2 } from "lucide-react";
import Link from "next/link";
import toast from "react-hot-toast";
import { Confirm } from "~/components/confirm";
import { import {
Credenza, Credenza,
CredenzaBody,
CredenzaClose,
CredenzaContent, CredenzaContent,
CredenzaDescription,
CredenzaFooter,
CredenzaHeader, CredenzaHeader,
CredenzaTitle, CredenzaTitle,
CredenzaDescription,
CredenzaBody,
CredenzaFooter,
CredenzaClose,
} from "~/components/custom_ui/credenza"; } from "~/components/custom_ui/credenza";
import { PaymentsTable } from "~/components/tables/payments-table"; import { PaymentsTable } from "~/components/tables/payments-table";
import type { OrdiniOrdineId } from "~/schemas/public/Ordini";
import { api } from "~/utils/api";
import { Confirm } from "~/components/confirm";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { CircleCheck, CircleSlash, ReceiptText, Trash2 } from "lucide-react";
import toast from "react-hot-toast";
import type { UsersId } from "~/schemas/public/Users";
import { cn } from "~/lib/utils";
import { import {
DropdownMenu, DropdownMenu,
DropdownMenuContent, DropdownMenuContent,
@ -26,9 +23,12 @@ import {
DropdownMenuSeparator, DropdownMenuSeparator,
DropdownMenuTrigger, DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu"; } from "~/components/ui/dropdown-menu";
import PaymentStatusEnum from "~/schemas/public/PaymentStatusEnum"; import { cn } from "~/lib/utils";
import Link from "next/link";
import OrderTypeEnum from "~/schemas/public/OrderTypeEnum"; import OrderTypeEnum from "~/schemas/public/OrderTypeEnum";
import type { OrdiniOrdineId } from "~/schemas/public/Ordini";
import PaymentStatusEnum from "~/schemas/public/PaymentStatusEnum";
import type { UsersId } from "~/schemas/public/Users";
import { api } from "~/utils/api";
export const OrdiniModal = ({ export const OrdiniModal = ({
isAdmin, isAdmin,

View file

@ -1,12 +1,12 @@
import { usePathname } from "next/navigation";
import { ARMinimizableLinks } from "~/components/navbar/mobile-nav";
import { cn } from "~/lib/utils";
import { Button } from "~/components/ui/button";
import { Expand, Minimize2 } from "lucide-react";
import { motion } from "framer-motion";
import { getCookie, setCookie } from "cookies-next/client"; import { getCookie, setCookie } from "cookies-next/client";
import { useEffect, useState } from "react";
import { add } from "date-fns"; import { add } from "date-fns";
import { motion } from "framer-motion";
import { Expand, Minimize2 } from "lucide-react";
import { usePathname } from "next/navigation";
import { useEffect, useState } from "react";
import { ARMinimizableLinks } from "~/components/navbar/mobile-nav";
import { Button } from "~/components/ui/button";
import { cn } from "~/lib/utils";
export const Sidebar = ({ export const Sidebar = ({
isAdmin, isAdmin,

View file

@ -1,11 +1,10 @@
import Link from "next/link";
import { useState } from "react";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
import { useEffect, type MouseEvent } from "react";
import { X } from "lucide-react"; import { X } from "lucide-react";
import type { Banners } from "~/schemas/public/Banners"; import Link from "next/link";
import { cn } from "~/lib/utils"; import { type MouseEvent, useEffect, useState } from "react";
import { IconMatrix, type IconType } from "~/components/IconComponents"; import { IconMatrix, type IconType } from "~/components/IconComponents";
import { cn } from "~/lib/utils";
import type { Banners } from "~/schemas/public/Banners";
export const BannerFactory = (bannerData: Banners) => { export const BannerFactory = (bannerData: Banners) => {
const NEW_BANNER_KEY = `bannercookie_${bannerData.idbanner}`; const NEW_BANNER_KEY = `bannercookie_${bannerData.idbanner}`;
@ -35,7 +34,6 @@ export const BannerFactory = (bannerData: Banners) => {
accentColor = "bg-indigo-800"; accentColor = "bg-indigo-800";
closeHoverColor = "hover:bg-indigo-500"; closeHoverColor = "hover:bg-indigo-500";
break; break;
case null:
default: default:
bgColor = "bg-indigo-600"; bgColor = "bg-indigo-600";
accentColor = "bg-indigo-800"; accentColor = "bg-indigo-800";
@ -98,6 +96,7 @@ export const BannerFactory = (bannerData: Banners) => {
</div> </div>
{bannerData.is_unskippable === false && ( {bannerData.is_unskippable === false && (
<button <button
type="button"
className={cn( className={cn(
"rounded-lg p-2 ring-offset-2 duration-150 hover:bg-indigo-500 focus:ring", "rounded-lg p-2 ring-offset-2 duration-150 hover:bg-indigo-500 focus:ring",
closeHoverColor, closeHoverColor,

View file

@ -1,27 +1,27 @@
"use client"; "use client";
import { differenceInDays, differenceInMinutes, format } from "date-fns";
import { Paperclip } from "lucide-react"; import { Paperclip } from "lucide-react";
import Link from "next/link";
import { ExtIcon } from "~/components/area-riservata/allegati";
import { import {
Credenza, Credenza,
CredenzaTrigger,
CredenzaContent,
CredenzaBody, CredenzaBody,
CredenzaHeader,
CredenzaDescription,
CredenzaTitle,
CredenzaFooter,
CredenzaClose, CredenzaClose,
CredenzaContent,
CredenzaDescription,
CredenzaFooter,
CredenzaHeader,
CredenzaTitle,
CredenzaTrigger,
} from "~/components/custom_ui/credenza"; } from "~/components/custom_ui/credenza";
import { Button, buttonVariants } from "~/components/ui/button";
import { api } from "~/utils/api";
import { LoadingPage } from "~/components/loading"; import { LoadingPage } from "~/components/loading";
import Link from "next/link"; import { Button, buttonVariants } from "~/components/ui/button";
import { UploadComponent } from "~/components/upload_modal";
import { cn } from "~/lib/utils"; import { cn } from "~/lib/utils";
import { ExtIcon } from "~/components/area-riservata/allegati"; import { useTranslation } from "~/providers/I18nProvider";
import type { Session } from "~/server/api/trpc"; import type { Session } from "~/server/api/trpc";
import type { ChatUserInfo } from "~/server/services/chat.service"; import type { ChatUserInfo } from "~/server/services/chat.service";
import { UploadComponent } from "~/components/upload_modal"; import { api } from "~/utils/api";
import { useTranslation } from "~/providers/I18nProvider";
import { differenceInDays, differenceInMinutes, format } from "date-fns";
type ChatAttachmentsProps = { type ChatAttachmentsProps = {
userData: Session; userData: Session;
@ -76,7 +76,7 @@ export const ChatAttachments = ({
<LoadingPage /> <LoadingPage />
) : ( ) : (
<> <>
{!attachments || attachments.length == 0 ? ( {!attachments || attachments.length === 0 ? (
<div className="flex h-full items-center justify-center"> <div className="flex h-full items-center justify-center">
<p className="text-center text-lg font-semibold text-gray-500"> <p className="text-center text-lg font-semibold text-gray-500">
{t.allegati.nessun_allegato} {t.allegati.nessun_allegato}
@ -111,7 +111,7 @@ export const ChatAttachments = ({
</Link> </Link>
<span <span
className="text-muted-foreground text-xs" className="text-muted-foreground text-xs"
key={new Date().getTime()} key={new Date().toString()}
> >
{TimeSince(file.created_at)} {TimeSince(file.created_at)}
</span> </span>

View file

@ -2,35 +2,35 @@
import { SendHorizontal, SmilePlusIcon, ThumbsUp } from "lucide-react"; import { SendHorizontal, SmilePlusIcon, ThumbsUp } from "lucide-react";
import { import {
type ChangeEvent,
useCallback, useCallback,
useEffect, useEffect,
useRef, useRef,
useState, useState,
type ChangeEvent,
} from "react"; } from "react";
import { Button } from "~/components/ui/button";
import {
AutosizeTextarea,
type AutosizeTextAreaRef,
} from "~/components/custom_ui/autoResizeTextArea";
import { api } from "~/utils/api";
import { ChatAttachments } from "~/components/chat/chat-attachments"; import { ChatAttachments } from "~/components/chat/chat-attachments";
import { useMediaQuery } from "~/hooks/use-media-query"; import {
import { useThrottledIsTypingMutation } from "~/hooks/chatHooks"; type AutosizeTextAreaRef,
import type { Session } from "~/server/api/trpc"; AutosizeTextarea,
import type { ChatsChatid } from "~/schemas/public/Chats"; } from "~/components/custom_ui/autoResizeTextArea";
import type { ChatUserInfo } from "~/server/services/chat.service"; import {
EmojiPicker,
EmojiPickerContent,
EmojiPickerSearch,
} from "~/components/custom_ui/emoji-picker";
import { Button } from "~/components/ui/button";
import { import {
Popover, Popover,
PopoverContent, PopoverContent,
PopoverTrigger, PopoverTrigger,
} from "~/components/ui/popover"; } from "~/components/ui/popover";
import { import { useThrottledIsTypingMutation } from "~/hooks/chatHooks";
EmojiPickerContent, import { useMediaQuery } from "~/hooks/use-media-query";
EmojiPickerSearch,
EmojiPicker,
} from "~/components/custom_ui/emoji-picker";
import { useTranslation } from "~/providers/I18nProvider"; import { useTranslation } from "~/providers/I18nProvider";
import type { ChatsChatid } from "~/schemas/public/Chats";
import type { Session } from "~/server/api/trpc";
import type { ChatUserInfo } from "~/server/services/chat.service";
import { api } from "~/utils/api";
type ChatBottombarProps = { type ChatBottombarProps = {
chatId: ChatsChatid; chatId: ChatsChatid;
@ -143,7 +143,7 @@ export default function ChatBottombar({
}} }}
> >
<EmojiPickerSearch <EmojiPickerSearch
placeholder={locale == "en" ? "Search..." : "Cerca..."} placeholder={locale === "en" ? "Search..." : "Cerca..."}
/> />
<EmojiPickerContent /> <EmojiPickerContent />
</EmojiPicker> </EmojiPicker>
@ -157,10 +157,10 @@ export default function ChatBottombar({
variant="ghost" variant="ghost"
className="shrink-0" className="shrink-0"
onClick={ onClick={
message.length != 0 ? () => handleSend() : () => handleThumbsUp() message.length !== 0 ? () => handleSend() : () => handleThumbsUp()
} }
> >
{message.length != 0 ? ( {message.length !== 0 ? (
<SendHorizontal size={20} className="text-muted-foreground" /> <SendHorizontal size={20} className="text-muted-foreground" />
) : ( ) : (
<ThumbsUp size={20} className="text-muted-foreground" /> <ThumbsUp size={20} className="text-muted-foreground" />

View file

@ -1,10 +1,9 @@
import * as React from "react";
import { cva, type VariantProps } from "class-variance-authority"; import { cva, type VariantProps } from "class-variance-authority";
import MessageLoading from "~/components/chat/message-loading";
import { cn } from "~/lib/utils";
import { Button, type ButtonProps } from "~/components/ui/button";
import { Check, CheckCheck } from "lucide-react"; import { Check, CheckCheck } from "lucide-react";
import * as React from "react";
import MessageLoading from "~/components/chat/message-loading";
import { Button, type ButtonProps } from "~/components/ui/button";
import { cn } from "~/lib/utils";
// ChatBubble // ChatBubble
const chatBubbleVariant = cva( const chatBubbleVariant = cva(
@ -64,8 +63,6 @@ export const ChatBubbleReadStatus = ({ isread }: ChatBubbleReadStatusProps) => {
} else { } else {
return <Check className="text-muted-foreground mt-2 size-4" />; return <Check className="text-muted-foreground mt-2 size-4" />;
} }
return null;
}; };
// ChatBubbleMessage // ChatBubbleMessage

View file

@ -1,27 +1,15 @@
"use client"; "use client";
import { cn } from "~/lib/utils"; import { AnimatePresence, motion } from "framer-motion";
import { Pencil, Trash2 } from "lucide-react";
import { import {
type FormEvent,
useCallback, useCallback,
useEffect, useEffect,
useRef, useRef,
useState, useState,
type FormEvent,
} from "react"; } from "react";
import { api } from "~/utils/api";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
import Input from "~/components/custom_ui/input";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from "~/components/ui/dialog";
import { Button } from "~/components/ui/button";
import { Pencil, Trash2 } from "lucide-react";
import type { MessagesMessageid } from "~/schemas/public/Messages";
import { AnimatePresence, motion } from "framer-motion";
import { import {
ChatBubble, ChatBubble,
ChatBubbleAction, ChatBubbleAction,
@ -31,6 +19,8 @@ import {
ChatBubbleTimestamp, ChatBubbleTimestamp,
} from "~/components/chat/chat-bubble"; } from "~/components/chat/chat-bubble";
import { ChatMessageList } from "~/components/chat/chat-message-list"; import { ChatMessageList } from "~/components/chat/chat-message-list";
import Input from "~/components/custom_ui/input";
import LoadingButton from "~/components/custom_ui/loading-button";
import { import {
AlertDialog, AlertDialog,
AlertDialogAction, AlertDialogAction,
@ -41,15 +31,25 @@ import {
AlertDialogHeader, AlertDialogHeader,
AlertDialogTitle, AlertDialogTitle,
} from "~/components/ui/alert-dialog"; } from "~/components/ui/alert-dialog";
import { useTranslation } from "~/providers/I18nProvider"; import { Button } from "~/components/ui/button";
import type { ChatMessage } from "~/server/services/messages.service"; import {
import type { UsersId } from "~/schemas/public/Users"; Dialog,
import type { WhoIsTyping } from "~/server/sse"; DialogContent,
import type { Session } from "~/server/api/trpc"; DialogDescription,
import type { ChatsChatid } from "~/schemas/public/Chats"; DialogHeader,
import type { LiveChat } from "~/hooks/chatHooks"; DialogTitle,
import LoadingButton from "~/components/custom_ui/loading-button"; } from "~/components/ui/dialog";
import { getUserColor, UserAvatar } from "~/components/user_avatar"; import { getUserColor, UserAvatar } from "~/components/user_avatar";
import type { LiveChat } from "~/hooks/chatHooks";
import { cn } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider";
import type { ChatsChatid } from "~/schemas/public/Chats";
import type { MessagesMessageid } from "~/schemas/public/Messages";
import type { UsersId } from "~/schemas/public/Users";
import type { Session } from "~/server/api/trpc";
import type { ChatMessage } from "~/server/services/messages.service";
import type { WhoIsTyping } from "~/server/sse";
import { api } from "~/utils/api";
type ChatListProps = { type ChatListProps = {
chatId: ChatsChatid; chatId: ChatsChatid;
@ -162,13 +162,14 @@ export const ChatList = ({
const isNextSameSender = const isNextSameSender =
index + 1 < messages.length && index + 1 < messages.length &&
messages[index + 1]?.sender == message.sender; messages[index + 1]?.sender === message.sender;
const isPreviousSameSender = const isPreviousSameSender =
index - 1 >= 0 && messages[index - 1]?.sender == message.sender; index - 1 >= 0 && messages[index - 1]?.sender === message.sender;
const isPrevSameDay = const isPrevSameDay =
index - 1 >= 0 && index - 1 >= 0 &&
// biome-ignore lint/style/noNonNullAssertion: <non lo so>
new Date(messages[index - 1]!.time).toDateString() === new Date(messages[index - 1]!.time).toDateString() ===
new Date(message.time).toDateString(); new Date(message.time).toDateString();
@ -229,7 +230,7 @@ export const ChatList = ({
> >
{message.message} {message.message}
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
{userData.id == message.sender && ( {userData.id === message.sender && (
<ChatBubbleReadStatus isread={message.isread} /> <ChatBubbleReadStatus isread={message.isread} />
)} )}
{message.time && ( {message.time && (
@ -315,7 +316,7 @@ const Typers = ({
return ( return (
<motion.div <motion.div
key={"typers" + messageLenght + index} key={`typers${messageLenght}${index}`}
layout layout
initial={{ opacity: 0, scale: 1, y: 50, x: 0 }} initial={{ opacity: 0, scale: 1, y: 50, x: 0 }}
animate={{ opacity: 1, scale: 1, y: 0, x: 0 }} animate={{ opacity: 1, scale: 1, y: 0, x: 0 }}

View file

@ -1,32 +1,10 @@
import { Search, SquarePen } from "lucide-react"; import { Search, SquarePen } from "lucide-react";
import { cn } from "~/lib/utils"; import Link from "next/link";
import { Button, buttonVariants } from "~/components/ui/button"; import { useRouter } from "next/router";
import { useMediaQuery } from "~/hooks/use-media-query";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import Input from "~/components/custom_ui/input"; import Input from "~/components/custom_ui/input";
import { import { Etichetta, EtichetteModal } from "~/components/etichette";
CommandDialog, import { LoadingPage } from "~/components/loading";
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "~/components/ui/command";
import { api } from "~/utils/api";
import { useRouter } from "next/router";
import type { ChatsChatid } from "~/schemas/public/Chats";
import {
ContextMenu,
ContextMenuContent,
ContextMenuItem,
ContextMenuSeparator,
ContextMenuSub,
ContextMenuSubContent,
ContextMenuSubTrigger,
ContextMenuTrigger,
} from "~/components/ui/context-menu";
import Link from "next/link";
import { import {
AlertDialog, AlertDialog,
AlertDialogAction, AlertDialogAction,
@ -37,11 +15,32 @@ import {
AlertDialogHeader, AlertDialogHeader,
AlertDialogTitle, AlertDialogTitle,
} from "~/components/ui/alert-dialog"; } from "~/components/ui/alert-dialog";
import { Etichetta, EtichetteModal } from "~/components/etichette"; import { Button, buttonVariants } from "~/components/ui/button";
import type { NonNullableUser } from "~/server/controllers/user.controller"; import {
import { LoadingPage } from "~/components/loading"; CommandDialog,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "~/components/ui/command";
import {
ContextMenu,
ContextMenuContent,
ContextMenuItem,
ContextMenuSeparator,
ContextMenuSub,
ContextMenuSubContent,
ContextMenuSubTrigger,
ContextMenuTrigger,
} from "~/components/ui/context-menu";
import { UserAvatar } from "~/components/user_avatar"; import { UserAvatar } from "~/components/user_avatar";
import { useMediaQuery } from "~/hooks/use-media-query";
import { cn } from "~/lib/utils";
import type { ChatsChatid } from "~/schemas/public/Chats";
import type { ActiveChatsType } from "~/server/controllers/chat.controller"; import type { ActiveChatsType } from "~/server/controllers/chat.controller";
import type { NonNullableUser } from "~/server/controllers/user.controller";
import { api } from "~/utils/api";
type LastMessage = { type LastMessage = {
message: string | null; message: string | null;
@ -385,6 +384,7 @@ const ChatSidebarContextMenu = ({
<ContextMenuSubContent className="w-48"> <ContextMenuSubContent className="w-48">
<ContextMenuItem asChild> <ContextMenuItem asChild>
<button <button
type="button"
aria-label="Edit Chat Labels" aria-label="Edit Chat Labels"
onClick={() => { onClick={() => {
setSelectedChat(chatid); setSelectedChat(chatid);

View file

@ -7,43 +7,43 @@ import {
User, User,
UserCog, UserCog,
} from "lucide-react"; } from "lucide-react";
import Link from "next/link";
import { cn } from "~/lib/utils";
import { Button, buttonVariants } from "~/components/ui/button";
import Image from "next/image"; import Image from "next/image";
import { import Link from "next/link";
Popover, import { useRouter } from "next/router";
PopoverContent, import { useCallback } from "react";
PopoverTrigger, import toast from "react-hot-toast";
} from "~/components/ui/popover"; import { EtichetteDisplayer } from "~/components/etichette";
import { import {
AlertDialog, AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent, AlertDialogContent,
AlertDialogDescription, AlertDialogDescription,
AlertDialogFooter, AlertDialogFooter,
AlertDialogHeader, AlertDialogHeader,
AlertDialogTitle, AlertDialogTitle,
AlertDialogTrigger, AlertDialogTrigger,
AlertDialogCancel,
AlertDialogAction,
} from "~/components/ui/alert-dialog"; } from "~/components/ui/alert-dialog";
import { api } from "~/utils/api"; import { Button, buttonVariants } from "~/components/ui/button";
import { useRouter } from "next/router"; import {
import toast from "react-hot-toast"; Popover,
PopoverContent,
PopoverTrigger,
} from "~/components/ui/popover";
import { Separator } from "~/components/ui/separator"; import { Separator } from "~/components/ui/separator";
import { EtichetteDisplayer } from "~/components/etichette";
import type { Session } from "~/server/api/trpc";
import type { ChatUserInfo } from "~/server/services/chat.service";
import type { ChatsChatid } from "~/schemas/public/Chats";
import type { OnlineStatus } from "~/server/sse";
import { import {
Tooltip, Tooltip,
TooltipContent, TooltipContent,
TooltipProvider, TooltipProvider,
TooltipTrigger, TooltipTrigger,
} from "~/components/ui/tooltip"; } from "~/components/ui/tooltip";
import { useCallback } from "react";
import { UserAvatar } from "~/components/user_avatar"; import { UserAvatar } from "~/components/user_avatar";
import { cn } from "~/lib/utils";
import type { ChatsChatid } from "~/schemas/public/Chats";
import type { Session } from "~/server/api/trpc";
import type { ChatUserInfo } from "~/server/services/chat.service";
import type { OnlineStatus } from "~/server/sse";
import { api } from "~/utils/api";
type ChatTopbarProps = { type ChatTopbarProps = {
chatId: ChatsChatid; chatId: ChatsChatid;

View file

@ -1,13 +1,13 @@
"use client"; "use client";
import type { ChatsChatid } from "~/schemas/public/Chats"; import { memo } from "react";
import ChatBottombar from "~/components/chat/chat-bottombar"; import ChatBottombar from "~/components/chat/chat-bottombar";
import { ChatList } from "~/components/chat/chat-list"; import { ChatList } from "~/components/chat/chat-list";
import ChatTopbar from "~/components/chat/chat-topbar"; import ChatTopbar from "~/components/chat/chat-topbar";
import { useLiveChat } from "~/hooks/chatHooks"; import { useLiveChat } from "~/hooks/chatHooks";
import { api } from "~/utils/api"; import type { ChatsChatid } from "~/schemas/public/Chats";
import type { Session } from "~/server/api/trpc"; import type { Session } from "~/server/api/trpc";
import { memo } from "react"; import { api } from "~/utils/api";
const Chat = memo( const Chat = memo(
({ chatId, userData }: { chatId: ChatsChatid; userData: Session }) => { ({ chatId, userData }: { chatId: ChatsChatid; userData: Session }) => {

View file

@ -8,6 +8,7 @@ export default function MessageLoading() {
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
className="text-foreground" className="text-foreground"
> >
<title>Loading</title>
<circle cx="4" cy="12" r="2" fill="currentColor"> <circle cx="4" cy="12" r="2" fill="currentColor">
<animate <animate
id="spinner_qFRN" id="spinner_qFRN"

View file

@ -1,14 +1,14 @@
"use client"; "use client";
import { useRouter } from "next/router"; import { CircleOff } from "lucide-react";
import Link from "next/link"; import Link from "next/link";
import { api } from "~/utils/api"; import { useRouter } from "next/router";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import Input from "~/components/custom_ui/input"; import Input from "~/components/custom_ui/input";
import { cn } from "~/lib/utils";
import { StaggeredFade } from "~/components/custom_ui/staggered-fade"; import { StaggeredFade } from "~/components/custom_ui/staggered-fade";
import { useTranslation } from "~/providers/I18nProvider";
import { useClickOutside } from "~/hooks/useClickOutside"; import { useClickOutside } from "~/hooks/useClickOutside";
import { CircleOff } from "lucide-react"; import { cn } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider";
import { api } from "~/utils/api";
export const CodiceBox = ({ export const CodiceBox = ({
className, className,
@ -62,7 +62,7 @@ const AutocompleteSearchBox = ({
useClickOutside([wrapperRef, listRef], () => setOpen(false)); useClickOutside([wrapperRef, listRef], () => setOpen(false));
useEffect(() => { useEffect(() => {
if (searchValue.trim() == "" || searchValue.length == 0) { if (searchValue.trim() === "" || searchValue.length === 0) {
setResults(options); setResults(options);
} else { } else {
setResults( setResults(
@ -100,7 +100,7 @@ const AutocompleteSearchBox = ({
className, className,
)} )}
/> />
<MovingText hidden={isFocused || searchValue != ""} /> <MovingText hidden={isFocused || searchValue !== ""} />
</div> </div>
{open && ( {open && (
<div <div
@ -116,6 +116,7 @@ const AutocompleteSearchBox = ({
navigationEnter && navigationEnter &&
"[&>li:first-child>a]:bg-neutral-100 [&>li:first-child>a]:underline [&>li:first-child>a]:underline-offset-2", "[&>li:first-child>a]:bg-neutral-100 [&>li:first-child>a]:underline [&>li:first-child>a]:underline-offset-2",
)} )}
// biome-ignore lint/a11y/noNoninteractiveElementToInteractiveRole: <need list>
role="listbox" role="listbox"
> >
{loading ? ( {loading ? (
@ -160,6 +161,7 @@ const MovingText = ({ hidden }: { hidden: boolean }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const [randomFrase, setRandomFrase] = useState<string>( const [randomFrase, setRandomFrase] = useState<string>(
// biome-ignore lint/style/noNonNullAssertion: <exists>
t.code_search_frases[0]!, t.code_search_frases[0]!,
); );
useEffect(() => { useEffect(() => {
@ -167,6 +169,7 @@ const MovingText = ({ hidden }: { hidden: boolean }) => {
const randomIndex = Math.floor( const randomIndex = Math.floor(
Math.random() * t.code_search_frases.length, Math.random() * t.code_search_frases.length,
); );
// biome-ignore lint/style/noNonNullAssertion: <exists>
setRandomFrase(t.code_search_frases[randomIndex]!); setRandomFrase(t.code_search_frases[randomIndex]!);
}, 5000); }, 5000);

View file

@ -1,15 +1,15 @@
import { forwardRef, useMemo, useState } from "react"; import { forwardRef, useMemo, useState } from "react";
import { HexColorPicker } from "react-colorful"; import { HexColorPicker } from "react-colorful";
import { cn } from "~/lib/utils";
import { useForwardedRef } from "~/lib/use_fowarded_ref";
import type { ButtonProps } from "~/components/ui/button"; import type { ButtonProps } from "~/components/ui/button";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { Input } from "~/components/ui/input";
import { import {
Popover, Popover,
PopoverContent, PopoverContent,
PopoverTrigger, PopoverTrigger,
} from "~/components/ui/popover"; } from "~/components/ui/popover";
import { Input } from "~/components/ui/input"; import { useForwardedRef } from "~/lib/use_fowarded_ref";
import { cn } from "~/lib/utils";
interface ColorPickerProps { interface ColorPickerProps {
value: string; value: string;

View file

@ -54,7 +54,7 @@ export const ComeFunziona = () => {
src={feature.image} src={feature.image}
width={400} width={400}
height={200} height={200}
alt={"img" + idx} alt={`img${idx}`}
/> />
</div> </div>
<div className="flex basis-1/2 flex-col"> <div className="flex basis-1/2 flex-col">

View file

@ -1,17 +1,17 @@
import { cn } from "~/lib/utils"; import type { ReactNode } from "react";
import { import {
AlertDialog, AlertDialog,
AlertDialogTrigger, AlertDialogAction,
AlertDialogCancel,
AlertDialogContent, AlertDialogContent,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogDescription, AlertDialogDescription,
AlertDialogFooter, AlertDialogFooter,
AlertDialogCancel, AlertDialogHeader,
AlertDialogAction, AlertDialogTitle,
AlertDialogTrigger,
} from "~/components/ui/alert-dialog"; } from "~/components/ui/alert-dialog";
import { buttonVariants } from "~/components/ui/button"; import { buttonVariants } from "~/components/ui/button";
import type { ReactNode } from "react"; import { cn } from "~/lib/utils";
export const Confirm = ({ export const Confirm = ({
children, children,
title, title,
@ -47,7 +47,7 @@ export const Confirm = ({
<AlertDialogDescription>{description}</AlertDialogDescription> <AlertDialogDescription>{description}</AlertDialogDescription>
</AlertDialogHeader> </AlertDialogHeader>
<AlertDialogFooter> <AlertDialogFooter>
<AlertDialogCancel onClick={() => onCancel && onCancel()}> <AlertDialogCancel onClick={() => onCancel?.()}>
{cancelText || "Annulla"} {cancelText || "Annulla"}
</AlertDialogCancel> </AlertDialogCancel>
<AlertDialogAction <AlertDialogAction

View file

@ -1,31 +1,31 @@
"use client"; "use client";
import {
type PropsWithChildren,
createContext,
useContext,
useEffect,
useState,
} from "react";
import {
Tooltip,
TooltipTrigger,
TooltipContent,
} from "~/components/ui/tooltip";
import {
Popover,
PopoverTrigger,
PopoverContent,
} from "~/components/ui/popover";
import type {
TooltipContentProps,
TooltipProps,
TooltipTriggerProps,
} from "@radix-ui/react-tooltip";
import type { import type {
PopoverContentProps, PopoverContentProps,
PopoverProps, PopoverProps,
PopoverTriggerProps, PopoverTriggerProps,
} from "@radix-ui/react-popover"; } from "@radix-ui/react-popover";
import type {
TooltipContentProps,
TooltipProps,
TooltipTriggerProps,
} from "@radix-ui/react-tooltip";
import {
createContext,
type PropsWithChildren,
useContext,
useEffect,
useState,
} from "react";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "~/components/ui/popover";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "~/components/ui/tooltip";
const TouchContext = createContext<boolean | undefined>(undefined); const TouchContext = createContext<boolean | undefined>(undefined);
const useTouch = () => useContext(TouchContext); const useTouch = () => useContext(TouchContext);

View file

@ -1,12 +1,12 @@
import { useAnimate, type AnimationSequence } from "framer-motion"; import { type AnimationSequence, useAnimate } from "framer-motion";
import { Button } from "~/components/ui/button";
import { IconMatrix, type IconType } from "~/components/IconComponents";
import { cn } from "~/lib/utils";
import { import {
type ComponentPropsWithoutRef,
forwardRef, forwardRef,
useImperativeHandle, useImperativeHandle,
type ComponentPropsWithoutRef,
} from "react"; } from "react";
import { IconMatrix, type IconType } from "~/components/IconComponents";
import { Button } from "~/components/ui/button";
import { cn } from "~/lib/utils";
const randomNumberBetween = (min: number, max: number) => { const randomNumberBetween = (min: number, max: number) => {
return Math.floor(Math.random() * (max - min + 1) + min); return Math.floor(Math.random() * (max - min + 1) + min);
@ -111,7 +111,6 @@ export const AnimatedButton = forwardRef<
<IconMatrix <IconMatrix
type={sparklesIcon} type={sparklesIcon}
className={cn( className={cn(
// eslint-disable-next-line better-tailwindcss/no-unregistered-classes
`absolute top-1/2 left-1/2 opacity-0 sparkle-${index}`, `absolute top-1/2 left-1/2 opacity-0 sparkle-${index}`,
sparklesClassName, sparklesClassName,
)} )}

View file

@ -1,12 +1,13 @@
"use client"; "use client";
import { useEffect } from "react";
import { import {
type MotionValue, type MotionValue,
motion, motion,
useSpring, useSpring,
useTransform, useTransform,
} from "framer-motion"; } from "framer-motion";
import { useEffect } from "react";
//DOC: https://www.cult-ui.com/docs/components/animated-number //DOC: https://www.cult-ui.com/docs/components/animated-number
interface AnimatedNumberProps { interface AnimatedNumberProps {

View file

@ -1,13 +1,13 @@
import { cn } from "~/lib/utils";
import { import {
forwardRef, forwardRef,
type Ref,
type TextareaHTMLAttributes,
useEffect, useEffect,
useImperativeHandle, useImperativeHandle,
useRef, useRef,
useState, useState,
type Ref,
type TextareaHTMLAttributes,
} from "react"; } from "react";
import { cn } from "~/lib/utils";
interface UseAutosizeTextAreaProps { interface UseAutosizeTextAreaProps {
textAreaRef: HTMLTextAreaElement | null; textAreaRef: HTMLTextAreaElement | null;
@ -84,6 +84,7 @@ export const AutosizeTextarea = forwardRef<
}); });
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
// biome-ignore lint/style/noNonNullAssertion: <it exists>
textArea: textAreaRef.current!, textArea: textAreaRef.current!,
focus: () => textAreaRef.current?.focus(), focus: () => textAreaRef.current?.focus(),
maxHeight, maxHeight,

View file

@ -1,6 +1,7 @@
"use client"; "use client";
import { useMediaQuery } from "~/hooks/use-media-query"; import { createContext, type ReactNode, useContext } from "react";
import type { Drawer as DrawerPrimitive } from "vaul";
import { import {
Dialog, Dialog,
DialogClose, DialogClose,
@ -22,9 +23,8 @@ import {
DrawerTitle, DrawerTitle,
DrawerTrigger, DrawerTrigger,
} from "~/components/ui/drawer"; } from "~/components/ui/drawer";
import { type Drawer as DrawerPrimitive } from "vaul"; import { useMediaQuery } from "~/hooks/use-media-query";
import { cn } from "~/lib/utils"; import { cn } from "~/lib/utils";
import { createContext, useContext, type ReactNode } from "react";
interface BaseProps { interface BaseProps {
children: ReactNode; children: ReactNode;

View file

@ -1,18 +1,26 @@
import { import {
type ColumnDef, type ColumnDef,
useReactTable,
getCoreRowModel,
flexRender,
getSortedRowModel,
type VisibilityState,
type ColumnFiltersState, type ColumnFiltersState,
getFilteredRowModel,
type SortingState,
getPaginationRowModel,
type ColumnSort, type ColumnSort,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
type RowSelectionState, type RowSelectionState,
type SortingState,
type Table as TableType, type Table as TableType,
useReactTable,
type VisibilityState,
} from "@tanstack/react-table"; } from "@tanstack/react-table";
import { useVirtualizer } from "@tanstack/react-virtual";
import { useEffect, useRef, useState } from "react";
import { DataTablePagination } from "~/components/custom_ui/dataTable-pagination";
import {
DataTableToolbar,
type PinnedFiltro,
type SearchFiltro,
} from "~/components/custom_ui/dataTable-toolbar";
import { import {
Table, Table,
TableBody, TableBody,
@ -21,15 +29,7 @@ import {
TableHeader, TableHeader,
TableRow, TableRow,
} from "~/components/ui/table"; } from "~/components/ui/table";
import { DataTablePagination } from "~/components/custom_ui/dataTable-pagination";
import {
DataTableToolbar,
type SearchFiltro,
type PinnedFiltro,
} from "~/components/custom_ui/dataTable-toolbar";
import { useVirtualizer } from "@tanstack/react-virtual";
import { cn } from "~/lib/utils"; import { cn } from "~/lib/utils";
import { useEffect, useRef, useState } from "react";
interface DataTableProps<TData, TValue> { interface DataTableProps<TData, TValue> {
columns: ColumnDef<TData, TValue>[]; columns: ColumnDef<TData, TValue>[];
@ -150,6 +150,7 @@ export function DataTable<TData, TValue>({
<TableBody className={tabClassName}> <TableBody className={tabClassName}>
{virtualizer.getVirtualItems().length ? ( {virtualizer.getVirtualItems().length ? (
virtualizer.getVirtualItems().map((virtualRow, index) => { virtualizer.getVirtualItems().map((virtualRow, index) => {
// biome-ignore lint/style/noNonNullAssertion: <always exists>
const row = rows[virtualRow.index]!; const row = rows[virtualRow.index]!;
return ( return (
<TableRow <TableRow

View file

@ -1,13 +1,8 @@
import type { Column } from "@tanstack/react-table"; import type { Column } from "@tanstack/react-table";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "~/components/ui/popover";
import { Button } from "~/components/ui/button";
import { CheckIcon, CirclePlus } from "lucide-react"; import { CheckIcon, CirclePlus } from "lucide-react";
import { Separator } from "~/components/ui/separator"; import type { ComponentType } from "react";
import { Badge } from "~/components/ui/badge"; import { Badge } from "~/components/ui/badge";
import { Button } from "~/components/ui/button";
import { import {
Command, Command,
CommandEmpty, CommandEmpty,
@ -17,8 +12,13 @@ import {
CommandList, CommandList,
CommandSeparator, CommandSeparator,
} from "~/components/ui/command"; } from "~/components/ui/command";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "~/components/ui/popover";
import { Separator } from "~/components/ui/separator";
import { cn } from "~/lib/utils"; import { cn } from "~/lib/utils";
import { type ComponentType } from "react";
interface DataTableFacetedFilterProps<TData, TValue> { interface DataTableFacetedFilterProps<TData, TValue> {
column?: Column<TData, TValue>; column?: Column<TData, TValue>;

View file

@ -1,4 +1,6 @@
import type { Table } from "@tanstack/react-table"; import type { Table } from "@tanstack/react-table";
import { Filter } from "lucide-react";
import { Button } from "~/components/ui/button";
import { import {
DropdownMenu, DropdownMenu,
DropdownMenuCheckboxItem, DropdownMenuCheckboxItem,
@ -7,8 +9,7 @@ import {
DropdownMenuSeparator, DropdownMenuSeparator,
DropdownMenuTrigger, DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu"; } from "~/components/ui/dropdown-menu";
import { Button } from "~/components/ui/button";
import { Filter } from "lucide-react";
interface DataTableViewOptionsProps<TData> { interface DataTableViewOptionsProps<TData> {
table: Table<TData>; table: Table<TData>;
columns_titles: Record<string, string>; columns_titles: Record<string, string>;

View file

@ -1,5 +1,12 @@
import type { Column } from "@tanstack/react-table"; import type { Column } from "@tanstack/react-table";
import { cn } from "~/lib/utils"; import {
ArrowDownIcon,
ArrowUpIcon,
ChevronsUpDown,
EyeOff,
} from "lucide-react";
import type { HTMLAttributes } from "react";
import { Button } from "~/components/ui/button";
import { import {
DropdownMenu, DropdownMenu,
DropdownMenuContent, DropdownMenuContent,
@ -7,14 +14,7 @@ import {
DropdownMenuSeparator, DropdownMenuSeparator,
DropdownMenuTrigger, DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu"; } from "~/components/ui/dropdown-menu";
import { Button } from "~/components/ui/button"; import { cn } from "~/lib/utils";
import {
ArrowDownIcon,
ArrowUpIcon,
ChevronsUpDown,
EyeOff,
} from "lucide-react";
import { type HTMLAttributes } from "react";
interface DataTableColumnHeaderProps<TData, TValue> interface DataTableColumnHeaderProps<TData, TValue>
extends HTMLAttributes<HTMLDivElement> { extends HTMLAttributes<HTMLDivElement> {

View file

@ -1,4 +1,11 @@
import type { Table } from "@tanstack/react-table"; import type { Table } from "@tanstack/react-table";
import {
ChevronFirst,
ChevronLast,
ChevronLeftIcon,
ChevronRightIcon,
} from "lucide-react";
import { Button } from "~/components/ui/button";
import { import {
Select, Select,
SelectContent, SelectContent,
@ -6,13 +13,7 @@ import {
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from "~/components/ui/select"; } from "~/components/ui/select";
import { Button } from "~/components/ui/button";
import {
ChevronFirst,
ChevronLast,
ChevronLeftIcon,
ChevronRightIcon,
} from "lucide-react";
interface DataTablePaginationProps<TData> { interface DataTablePaginationProps<TData> {
table: Table<TData>; table: Table<TData>;
hasSelectRow?: boolean; hasSelectRow?: boolean;

View file

@ -1,10 +1,10 @@
import type { Table } from "@tanstack/react-table"; import type { Table } from "@tanstack/react-table";
import Input from "~/components/custom_ui/input";
import { DataTableViewOptions } from "~/components/custom_ui/dataTable-ViewToggle";
import { Button } from "~/components/ui/button";
import { DataTableFacetedFilter } from "~/components/custom_ui/dataTable-FacetedFilter";
import { RotateCcw } from "lucide-react"; import { RotateCcw } from "lucide-react";
import type { ComponentType } from "react"; import type { ComponentType } from "react";
import { DataTableFacetedFilter } from "~/components/custom_ui/dataTable-FacetedFilter";
import { DataTableViewOptions } from "~/components/custom_ui/dataTable-ViewToggle";
import Input from "~/components/custom_ui/input";
import { Button } from "~/components/ui/button";
export type PinnedFiltro = { export type PinnedFiltro = {
title: string; title: string;
@ -59,8 +59,7 @@ export function DataTableToolbar<TData>(props: {
className="mt-0 h-8 w-[150px]" className="mt-0 h-8 w-[150px]"
/> />
))} ))}
{pinnedColumns && {pinnedColumns?.map(
pinnedColumns.map(
(column) => (column) =>
table.getColumn(column.columnName) && ( table.getColumn(column.columnName) && (
<DataTableFacetedFilter <DataTableFacetedFilter

View file

@ -11,7 +11,7 @@ import {
// useSkinTone, // useSkinTone,
} from "frimousse"; } from "frimousse";
import { LoaderIcon, SearchIcon } from "lucide-react"; import { LoaderIcon, SearchIcon } from "lucide-react";
import * as React from "react"; import type * as React from "react";
// import { Button } from "~/components/ui/button"; // import { Button } from "~/components/ui/button";
// import { // import {

View file

@ -1,6 +1,5 @@
"use client"; "use client";
import { cn } from "~/lib/utils";
import { Slot } from "@radix-ui/react-slot"; import { Slot } from "@radix-ui/react-slot";
import { import {
FileArchiveIcon, FileArchiveIcon,
@ -12,8 +11,15 @@ import {
FileVideoIcon, FileVideoIcon,
} from "lucide-react"; } from "lucide-react";
import { import {
type ChangeEvent,
type ComponentPropsWithoutRef,
createContext, createContext,
type DragEvent,
forwardRef, forwardRef,
type KeyboardEvent,
type MouseEvent,
type ReactNode,
type RefObject,
useCallback, useCallback,
useContext, useContext,
useEffect, useEffect,
@ -22,14 +28,8 @@ import {
useMemo, useMemo,
useRef, useRef,
useSyncExternalStore, useSyncExternalStore,
type ChangeEvent,
type ComponentPropsWithoutRef,
type DragEvent,
type KeyboardEvent,
type MouseEvent,
type ReactNode,
type RefObject,
} from "react"; } from "react";
import { cn } from "~/lib/utils";
const ROOT_NAME = "FileUpload"; const ROOT_NAME = "FileUpload";
const DROPZONE_NAME = "FileUploadDropzone"; const DROPZONE_NAME = "FileUploadDropzone";
@ -340,15 +340,14 @@ const FileUploadRoot = forwardRef<HTMLDivElement, FileUploadRootProps>(
value, value,
defaultValue, defaultValue,
onValueChange, onValueChange,
/* eslint-disable @typescript-eslint/no-unused-vars */ //onAccept,
onAccept, //onFileAccept,
onFileAccept, //onFileReject,
onFileReject, //onFileValidate,
onFileValidate, //onUpload,
onUpload,
accept, accept,
maxFiles, //maxFiles,
maxSize, //maxSize,
dir: dirProp, dir: dirProp,
label, label,
name, name,
@ -361,7 +360,6 @@ const FileUploadRoot = forwardRef<HTMLDivElement, FileUploadRootProps>(
className, className,
...rootProps ...rootProps
} = props; } = props;
/* eslint-enable @typescript-eslint/no-unused-vars */
const inputId = useId(); const inputId = useId();
const dropzoneId = useId(); const dropzoneId = useId();
@ -1042,7 +1040,7 @@ const FileUploadItemPreview = forwardRef<
if (isImage) { if (isImage) {
return ( return (
// eslint-disable-next-line @next/next/no-img-element // biome-ignore lint/a11y/noNoninteractiveElementInteractions: <intended>
<img <img
src={URL.createObjectURL(file)} src={URL.createObjectURL(file)}
alt={file.name} alt={file.name}
@ -1186,6 +1184,7 @@ const FileUploadItemProgress = forwardRef<
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
> >
<title>Progress</title>
<circle <circle
className="text-primary/20" className="text-primary/20"
strokeWidth="2" strokeWidth="2"

View file

@ -1,6 +1,6 @@
import * as React from "react";
import type * as LabelPrimitive from "@radix-ui/react-label"; import type * as LabelPrimitive from "@radix-ui/react-label";
import { Slot } from "@radix-ui/react-slot"; import { Slot } from "@radix-ui/react-slot";
import * as React from "react";
import { import {
Controller, Controller,
type ControllerProps, type ControllerProps,
@ -9,9 +9,8 @@ import {
FormProvider, FormProvider,
useFormContext, useFormContext,
} from "react-hook-form"; } from "react-hook-form";
import { cn } from "src/lib/utils";
import { Label } from "src/components/ui/label"; import { Label } from "src/components/ui/label";
import { cn } from "src/lib/utils";
import { env } from "~/env.mjs"; import { env } from "~/env.mjs";
const Form = FormProvider; const Form = FormProvider;

View file

@ -1,6 +1,6 @@
import { import {
forwardRef,
type ComponentPropsWithoutRef, type ComponentPropsWithoutRef,
forwardRef,
type ReactNode, type ReactNode,
} from "react"; } from "react";
import Input from "~/components/custom_ui/input"; import Input from "~/components/custom_ui/input";
@ -15,14 +15,14 @@ const InputWIcon = forwardRef<HTMLInputElement, InputWIconProps>(
return ( return (
<div className="relative"> <div className="relative">
<Input <Input
className={cn("peer", iconPosition == "start" ? "ps-9" : "pe-9")} className={cn("peer", iconPosition === "start" ? "ps-9" : "pe-9")}
{...props} {...props}
ref={ref} ref={ref}
/> />
<div <div
className={cn( className={cn(
"pointer-events-none absolute inset-y-0 flex items-center justify-center text-muted-foreground/80 peer-disabled:opacity-50", "pointer-events-none absolute inset-y-0 flex items-center justify-center text-muted-foreground/80 peer-disabled:opacity-50",
iconPosition == "start" ? "start-0 ps-3" : "end-0 pe-3", iconPosition === "start" ? "start-0 ps-3" : "end-0 pe-3",
)} )}
> >
{children} {children}

View file

@ -1,5 +1,6 @@
import { type ReactNode } from "react"; import type { ReactNode } from "react";
import { cn } from "~/lib/utils"; import { cn } from "~/lib/utils";
const DualInputLayout = (props: { const DualInputLayout = (props: {
children1: ReactNode; children1: ReactNode;
children2: ReactNode; children2: ReactNode;

View file

@ -1,9 +1,9 @@
import { LoaderCircle } from "lucide-react";
import { import {
Button, Button,
buttonVariants,
type ButtonProps, type ButtonProps,
buttonVariants,
} from "~/components/ui/button"; } from "~/components/ui/button";
import { LoaderCircle } from "lucide-react";
import { cn } from "~/lib/utils"; import { cn } from "~/lib/utils";
const LoadingButton = ({ const LoadingButton = ({

View file

@ -1,7 +1,18 @@
"use client"; "use client";
import { CheckIcon, ChevronsUpDownIcon, XIcon } from "lucide-react"; import { CheckIcon, ChevronsUpDownIcon, XIcon } from "lucide-react";
import { cn } from "~/lib/utils"; import {
type ComponentPropsWithoutRef,
createContext,
type ReactNode,
useCallback,
useContext,
useEffect,
useLayoutEffect,
useRef,
useState,
} from "react";
import { Badge } from "~/components/ui/badge";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { import {
Command, Command,
@ -17,18 +28,7 @@ import {
PopoverContent, PopoverContent,
PopoverTrigger, PopoverTrigger,
} from "~/components/ui/popover"; } from "~/components/ui/popover";
import { import { cn } from "~/lib/utils";
createContext,
useCallback,
useContext,
useEffect,
useLayoutEffect,
useRef,
useState,
type ComponentPropsWithoutRef,
type ReactNode,
} from "react";
import { Badge } from "~/components/ui/badge";
type MultiSelectContextType = { type MultiSelectContextType = {
open: boolean; open: boolean;
@ -273,8 +273,13 @@ export function MultiSelectContent({
} }
/> />
) : ( ) : (
// eslint-disable-next-line jsx-a11y/no-autofocus // biome-ignore lint/a11y/noAriaHiddenOnFocusable: <intended>
<button autoFocus aria-hidden="true" className="sr-only" /> <button
autoFocus
aria-hidden="true"
className="sr-only"
type="button"
/>
)} )}
<CommandList> <CommandList>
{canSearch && ( {canSearch && (

View file

@ -1,10 +1,9 @@
/* eslint-disable better-tailwindcss/no-unregistered-classes */
import { useVirtualizer } from "@tanstack/react-virtual"; import { useVirtualizer } from "@tanstack/react-virtual";
import { useRef, useState, type JSX } from "react"; import { type JSX, useRef, useState } from "react";
import ReactSelect, { import ReactSelect, {
type MenuListProps,
type GroupBase,
type CSSObjectWithLabel, type CSSObjectWithLabel,
type GroupBase,
type MenuListProps,
} from "react-select"; } from "react-select";
import { cn } from "~/lib/utils"; import { cn } from "~/lib/utils";
@ -282,11 +281,13 @@ type RepackValues = {
export const RepackValues = ({ values, options }: RepackValues) => { export const RepackValues = ({ values, options }: RepackValues) => {
if (Array.isArray(values)) { if (Array.isArray(values)) {
return values.map((v) => ({ return values.map((v) => ({
// biome-ignore lint/style/noNonNullAssertion: <intended>
label: options[Number.parseInt(v)]!, label: options[Number.parseInt(v)]!,
value: v, value: v,
})); }));
} }
return { return {
// biome-ignore lint/style/noNonNullAssertion: <intended>
label: options[Number.parseInt(values)]!, label: options[Number.parseInt(values)]!,
value: values, value: values,
}; };

View file

@ -3,19 +3,19 @@
import * as DialogPrimitive from "@radix-ui/react-dialog"; import * as DialogPrimitive from "@radix-ui/react-dialog";
import { X } from "lucide-react"; import { X } from "lucide-react";
import { import {
createContext,
forwardRef,
useContext,
useEffect,
useRef,
useState,
type ComponentPropsWithoutRef, type ComponentPropsWithoutRef,
createContext,
type Dispatch, type Dispatch,
type ElementRef, type ElementRef,
forwardRef,
type HTMLAttributes, type HTMLAttributes,
type PointerEvent, type PointerEvent,
type ReactNode, type ReactNode,
type SetStateAction, type SetStateAction,
useContext,
useEffect,
useRef,
useState,
} from "react"; } from "react";
import { cn } from "~/lib/utils"; import { cn } from "~/lib/utils";

View file

@ -1,7 +1,7 @@
"use client"; "use client";
import { cn } from "~/lib/utils";
import { motion, useInView } from "framer-motion"; import { motion, useInView } from "framer-motion";
import * as React from "react"; import * as React from "react";
import { cn } from "~/lib/utils";
type TextStaggeredFadeProps = { type TextStaggeredFadeProps = {
text: string; text: string;

View file

@ -1,7 +1,6 @@
import { Plus } from "lucide-react";
import { useState } from "react"; import { useState } from "react";
import { cn } from "~/lib/utils"; import { Button } from "~/components/ui/button";
import type { ChatsChatid } from "~/schemas/public/Chats";
import { api } from "~/utils/api";
import { import {
Dialog, Dialog,
DialogContent, DialogContent,
@ -9,9 +8,6 @@ import {
DialogHeader, DialogHeader,
DialogTitle, DialogTitle,
} from "~/components/ui/dialog"; } from "~/components/ui/dialog";
import type { EtichetteIdEtichetta } from "~/schemas/public/Etichette";
import { Button } from "~/components/ui/button";
import { Separator } from "~/components/ui/separator";
import { import {
Select, Select,
SelectContent, SelectContent,
@ -19,7 +15,11 @@ import {
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from "~/components/ui/select"; } from "~/components/ui/select";
import { Plus } from "lucide-react"; import { Separator } from "~/components/ui/separator";
import { cn } from "~/lib/utils";
import type { ChatsChatid } from "~/schemas/public/Chats";
import type { EtichetteIdEtichetta } from "~/schemas/public/Etichette";
import { api } from "~/utils/api";
export const EtichetteDisplayer = ({ export const EtichetteDisplayer = ({
chatId, chatId,
@ -50,6 +50,7 @@ export const EtichetteDisplayer = ({
/> />
))} ))}
<button <button
type="button"
onClick={() => setOpenEdit(true)} onClick={() => setOpenEdit(true)}
className="flex items-center justify-center rounded-lg border p-1" className="flex items-center justify-center rounded-lg border p-1"
> >
@ -185,7 +186,7 @@ function hexToRgb(hex: string): { r: number; g: number; b: number } {
} }
export function colorIsDarkSimple(color: string) { export function colorIsDarkSimple(color: string) {
if (color == "#FFFFFF") return false; if (color === "#FFFFFF") return false;
const { r, g, b } = hexToRgb(color); const { r, g, b } = hexToRgb(color);
return r * 0.299 + g * 0.587 + b * 0.114 <= 186; return r * 0.299 + g * 0.587 + b * 0.114 <= 186;
} }

View file

@ -1,7 +1,7 @@
import Link from "next/link"; import Link from "next/link";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { useTranslation } from "~/providers/I18nProvider";
import { HomeIcon } from "~/components/IconComponents"; import { HomeIcon } from "~/components/IconComponents";
import { useTranslation } from "~/providers/I18nProvider";
export default function FailedAnnuncioLoading() { export default function FailedAnnuncioLoading() {
const router = useRouter(); const router = useRouter();
@ -17,6 +17,7 @@ export default function FailedAnnuncioLoading() {
<p className="text-neutral-600">{t.annuncio_load_fail.sottotitolo}</p> <p className="text-neutral-600">{t.annuncio_load_fail.sottotitolo}</p>
<div className="flex flex-wrap items-center justify-center gap-3"> <div className="flex flex-wrap items-center justify-center gap-3">
<button <button
type="button"
onClick={() => { onClick={() => {
router.back(); router.back();
}} }}

View file

@ -6,10 +6,7 @@ export const Footer = () => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<div className="mt-auto"> <div className="mt-auto">
<footer <footer className="bg-muted text-muted-foreground bottom-0 z-40 w-full">
aria-label="Site Footer"
className="bg-muted text-muted-foreground bottom-0 z-40 w-full"
>
<div className="mx-auto max-w-6xl px-4 py-6 sm:px-6 lg:px-8"> <div className="mx-auto max-w-6xl px-4 py-6 sm:px-6 lg:px-8">
<div className="text-center"> <div className="text-center">
<Link <Link
@ -80,10 +77,7 @@ export const MiniFooter = () => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<div className="mt-auto flex w-full"> <div className="mt-auto flex w-full">
<footer <footer className="dark:bg-primary z-40 w-full bg-neutral-100 text-neutral-700 dark:text-white">
aria-label="Site Footer"
className="dark:bg-primary z-40 w-full bg-neutral-100 text-neutral-700 dark:text-white"
>
<div className="mx-auto max-w-5xl px-2 py-2 sm:px-6 lg:px-8"> <div className="mx-auto max-w-5xl px-2 py-2 sm:px-6 lg:px-8">
<div className="text-center"> <div className="text-center">
<Link <Link

View file

@ -1,21 +1,21 @@
"use client"; "use client";
import { import {
Circle,
MapContainer, MapContainer,
TileLayer,
Marker, Marker,
Popup, Popup,
Circle, TileLayer,
useMapEvents, useMapEvents,
} from "react-leaflet"; } from "react-leaflet";
import "leaflet/dist/leaflet.css"; import "leaflet/dist/leaflet.css";
import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css"; import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css";
import "leaflet-defaulticon-compatibility"; import "leaflet-defaulticon-compatibility";
import { cn } from "~/lib/utils";
import MapMarker from "~/components/map/map_marker";
import { Marker as CustomMarker } from "~/components/map/custom_marker";
import { Home } from "lucide-react"; import { Home } from "lucide-react";
import { Marker as CustomMarker } from "~/components/map/custom_marker";
import MapMarker from "~/components/map/map_marker";
import { cn } from "~/lib/utils";
type LatLon = { type LatLon = {
lat: number; lat: number;
@ -63,7 +63,7 @@ const MedianPoint = (pos: posData[]) => {
return { lat, lng }; return { lat, lng };
}; };
const Map = ({ const MapComp = ({
posix, posix,
autocenter, autocenter,
zoom = defaults.zoom, zoom = defaults.zoom,
@ -196,7 +196,7 @@ const Map = ({
); );
}; };
export default Map; export default MapComp;
/* /*
const PuntiInteresse: { const PuntiInteresse: {

View file

@ -1,14 +1,24 @@
import { import {
useState, type DivIconOptions,
useId, DomEvent,
useMemo, divIcon,
type LeafletEventHandlerFn,
type LeafletEventHandlerFnMap,
type Marker as LeafletMarker,
type PointExpression,
type PointTuple,
} from "leaflet";
import {
type ComponentType,
forwardRef,
isValidElement,
type ReactElement, type ReactElement,
useCallback, useCallback,
isValidElement,
type ComponentType,
useLayoutEffect,
forwardRef,
useEffect, useEffect,
useId,
useLayoutEffect,
useMemo,
useState,
} from "react"; } from "react";
import { createPortal } from "react-dom"; import { createPortal } from "react-dom";
import { isValidElementType } from "react-is"; import { isValidElementType } from "react-is";
@ -16,22 +26,12 @@ import {
Marker as ReactLeafletMarker, Marker as ReactLeafletMarker,
type MarkerProps as ReactLeafletMarkerProps, type MarkerProps as ReactLeafletMarkerProps,
} from "react-leaflet"; } from "react-leaflet";
import {
divIcon,
DomEvent,
type LeafletEventHandlerFn,
type LeafletEventHandlerFnMap,
type PointExpression,
type DivIconOptions,
type Marker as LeafletMarker,
type PointTuple,
} from "leaflet";
import { type SetRequired } from "type-fest";
import { import {
createHtmlPortalNode, createHtmlPortalNode,
OutPortal,
InPortal, InPortal,
OutPortal,
} from "react-reverse-portal"; } from "react-reverse-portal";
import type { SetRequired } from "type-fest";
const getCoordsFromPointExpression = (expression?: PointExpression) => { const getCoordsFromPointExpression = (expression?: PointExpression) => {
if (!expression) return []; if (!expression) return [];
@ -127,7 +127,8 @@ type CoreComponentMarkerOpts = {
}; };
type UnionKeys<T> = T extends T ? keyof T : never; type UnionKeys<T> = T extends T ? keyof T : never;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// biome-ignore lint/suspicious/noExplicitAny: <intended>
type StrictUnionHelper<T, TAll> = T extends any type StrictUnionHelper<T, TAll> = T extends any
? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, undefined>> ? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, undefined>>
: never; : never;
@ -147,7 +148,8 @@ type BaseMarkerProps<AdditionalIconTypes = never> = Omit<
"icon" "icon"
> & { > & {
/** A {@link ReactElement} representing the Markers icon, or any type from [react-leaflet Marker](https://react-leaflet.js.org/docs/api-components/#marker) component. */ /** A {@link ReactElement} representing the Markers icon, or any type from [react-leaflet Marker](https://react-leaflet.js.org/docs/api-components/#marker) component. */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// biome-ignore lint/suspicious/noExplicitAny: <intended>
icon: ReactElement<any> | AdditionalIconTypes; icon: ReactElement<any> | AdditionalIconTypes;
/** /**
@ -182,7 +184,7 @@ const ComponentMarker = forwardRef<LeafletMarker, BaseMarkerProps>(
) => { ) => {
const [markerRendered, setMarkerRendered] = useState(false); const [markerRendered, setMarkerRendered] = useState(false);
const [, setChangeCount] = useState(0); const [, setChangeCount] = useState(0);
const id = "marker-" + useId(); const id = `marker-${useId()}`;
const portalNode = useMemo( const portalNode = useMemo(
() => () =>

View file

@ -1,6 +1,6 @@
"use client"; "use client";
import { cn } from "~/lib/utils";
import type { ReactNode } from "react"; import type { ReactNode } from "react";
import { cn } from "~/lib/utils";
interface MapMarkerProps { interface MapMarkerProps {
label: ReactNode; label: ReactNode;

View file

@ -1,9 +1,9 @@
import { useState } from "react";
import { useRouter } from "next/router";
import { setCookie } from "cookies-next/client"; import { setCookie } from "cookies-next/client";
import { EngFlag, ItaFlag } from "~/components/svgs";
import LoadingButton from "~/components/custom_ui/loading-button";
import { add } from "date-fns"; import { add } from "date-fns";
import { useRouter } from "next/router";
import { useState } from "react";
import LoadingButton from "~/components/custom_ui/loading-button";
import { EngFlag, ItaFlag } from "~/components/svgs";
export const LangToggle = () => { export const LangToggle = () => {
const router = useRouter(); const router = useRouter();

View file

@ -1,7 +1,11 @@
"use client"; "use client";
import { LogIn, LogOut } from "lucide-react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { useSession } from "~/providers/SessionProvider"; import { IconMatrix, type IconType } from "~/components/IconComponents";
import { api } from "~/utils/api"; import { LoadingSpinner } from "~/components/spinner";
import { Button } from "~/components/ui/button";
import { import {
DropdownMenu, DropdownMenu,
DropdownMenuContent, DropdownMenuContent,
@ -11,15 +15,11 @@ import {
DropdownMenuSeparator, DropdownMenuSeparator,
DropdownMenuTrigger, DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu"; } from "~/components/ui/dropdown-menu";
import { Button } from "~/components/ui/button";
import Link from "next/link";
import { LogIn, LogOut } from "lucide-react";
import { useTranslation } from "~/providers/I18nProvider";
import { cn } from "~/lib/utils";
import { IconMatrix, type IconType } from "~/components/IconComponents";
import { usePathname } from "next/navigation";
import { UserAvatar } from "~/components/user_avatar"; import { UserAvatar } from "~/components/user_avatar";
import { LoadingSpinner } from "~/components/spinner"; import { cn } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider";
import { useSession } from "~/providers/SessionProvider";
import { api } from "~/utils/api";
type LoginButtonProps = { type LoginButtonProps = {
open: boolean; open: boolean;

View file

@ -1,7 +1,8 @@
import Link from "next/link"; import Link from "next/link";
import { cn } from "~/lib/utils";
import { LogoSvg } from "~/components/svgs"; import { LogoSvg } from "~/components/svgs";
import { cn } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider"; import { useTranslation } from "~/providers/I18nProvider";
type MainNavProps = { type MainNavProps = {
pathname: string; pathname: string;
}; };

View file

@ -1,7 +1,13 @@
import type { ReactNode } from "react"; import { AlignLeft, Home } from "lucide-react";
import { cn } from "~/lib/utils";
import { Button } from "~/components/ui/button";
import Link, { type LinkProps } from "next/link"; import Link, { type LinkProps } from "next/link";
import { useRouter } from "next/navigation";
import type { ReactNode } from "react";
import { IconMatrix } from "~/components/IconComponents";
import { LangToggle } from "~/components/navbar/lang-toggle";
import { UserHeaderSection } from "~/components/navbar/login-button";
import { ASvg, LogoSvg } from "~/components/svgs";
import { Button } from "~/components/ui/button";
import { Separator } from "~/components/ui/separator";
import { import {
Sheet, Sheet,
SheetContent, SheetContent,
@ -10,16 +16,10 @@ import {
SheetTitle, SheetTitle,
SheetTrigger, SheetTrigger,
} from "~/components/ui/sheet"; } from "~/components/ui/sheet";
import { AlignLeft, Home } from "lucide-react";
import { useRouter } from "next/navigation";
import { useSession } from "~/providers/SessionProvider";
import { IconMatrix } from "~/components/IconComponents";
import { useTranslation } from "~/providers/I18nProvider";
import { Separator } from "~/components/ui/separator";
import { UserHeaderSection } from "~/components/navbar/login-button";
import { ASvg, LogoSvg } from "~/components/svgs";
import { useMediaQuery } from "~/hooks/use-media-query"; import { useMediaQuery } from "~/hooks/use-media-query";
import { LangToggle } from "~/components/navbar/lang-toggle"; import { cn } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider";
import { useSession } from "~/providers/SessionProvider";
type MobileNavProps = { type MobileNavProps = {
pathname: string; pathname: string;
@ -74,7 +74,7 @@ export function MobileNav({
<div className="flex h-full flex-col space-y-2 pt-4"> <div className="flex h-full flex-col space-y-2 pt-4">
{pathname.startsWith("/area-riservata") && ( {pathname.startsWith("/area-riservata") && (
<> <>
{session && session.user && ( {session?.user && (
<AreaRiservataLinks <AreaRiservataLinks
isAdmin={session.user.isAdmin} isAdmin={session.user.isAdmin}
pathname={pathname} pathname={pathname}
@ -166,7 +166,6 @@ function MobileLink({
onOpenChange?.(false); onOpenChange?.(false);
} else { } else {
router.push( router.push(
// eslint-disable-next-line @typescript-eslint/no-base-to-string
href.toString(), href.toString(),
); );
onOpenChange?.(false); onOpenChange?.(false);

View file

@ -1,19 +1,18 @@
"use client"; "use client";
import { Search } from "lucide-react"; import { Search } from "lucide-react";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import { CodiceBox } from "~/components/codiceRicerca";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { import {
Dialog, Dialog,
DialogTrigger,
DialogContent, DialogContent,
DialogDescription,
DialogHeader, DialogHeader,
DialogTitle, DialogTitle,
DialogDescription, DialogTrigger,
} from "~/components/ui/dialog"; } from "~/components/ui/dialog";
import { CodiceBox } from "~/components/codiceRicerca";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
export function RicercaCommand() { export function RicercaCommand() {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);

View file

@ -1,6 +1,6 @@
import { Button } from "~/components/ui/button";
import { Settings } from "lucide-react"; import { Settings } from "lucide-react";
import { LangToggle } from "~/components/navbar/lang-toggle"; import { LangToggle } from "~/components/navbar/lang-toggle";
import { Button } from "~/components/ui/button";
import { import {
Popover, Popover,

View file

@ -1,11 +1,11 @@
"use client"; "use client";
import { usePathname } from "next/navigation"; import { usePathname } from "next/navigation";
import { MainNav } from "~/components/navbar/main-nav";
import { MobileNav } from "~/components/navbar/mobile-nav";
import { useState } from "react"; import { useState } from "react";
import { UserHeaderSection } from "~/components/navbar/login-button"; import { UserHeaderSection } from "~/components/navbar/login-button";
import { SettingsPopover } from "~/components/navbar/settings-modal"; import { MainNav } from "~/components/navbar/main-nav";
import { MobileNav } from "~/components/navbar/mobile-nav";
import { RicercaCommand } from "~/components/navbar/ricerca_command"; import { RicercaCommand } from "~/components/navbar/ricerca_command";
import { SettingsPopover } from "~/components/navbar/settings-modal";
export function SiteHeader() { export function SiteHeader() {
const pathname = usePathname(); const pathname = usePathname();

View file

@ -1,6 +1,6 @@
import { motion, type Transition } from "framer-motion";
import { Moon, Sun } from "lucide-react"; import { Moon, Sun } from "lucide-react";
import { useTheme } from "next-themes"; import { useTheme } from "next-themes";
import { motion, type Transition } from "framer-motion";
import { cn } from "~/lib/utils"; import { cn } from "~/lib/utils";
export const ThemeSwitch = () => { export const ThemeSwitch = () => {
@ -19,7 +19,7 @@ export const ThemeSwitch = () => {
onClick={() => setTheme(theme === "light" ? "dark" : "light")} onClick={() => setTheme(theme === "light" ? "dark" : "light")}
className={cn( className={cn(
`flex h-10 w-20 rounded-full bg-neutral-200 p-[5px] shadow-inner hover:cursor-pointer dark:bg-neutral-700`, `flex h-10 w-20 rounded-full bg-neutral-200 p-[5px] shadow-inner hover:cursor-pointer dark:bg-neutral-700`,
theme == "light" && "place-content-end", theme === "light" && "place-content-end",
)} )}
> >
<motion.div <motion.div
@ -31,7 +31,7 @@ export const ThemeSwitch = () => {
transition={spring} transition={spring}
> >
<motion.div whileTap={{ rotate: 360 }}> <motion.div whileTap={{ rotate: 360 }}>
{theme == "light" ? ( {theme === "light" ? (
<Sun className="size-6 stroke-yellow-300" /> <Sun className="size-6 stroke-yellow-300" />
) : ( ) : (
<Moon className="size-6 stroke-slate-200" /> <Moon className="size-6 stroke-slate-200" />

View file

@ -1,4 +1,5 @@
import { CheckCircle, AlertCircle, Loader2 } from "lucide-react"; import { AlertCircle, CheckCircle, Loader2 } from "lucide-react";
type PaymentStatus = "success" | "processing" | "error"; type PaymentStatus = "success" | "processing" | "error";
interface PaymentStatusProps { interface PaymentStatusProps {

View file

@ -186,6 +186,7 @@ const CountrySelect = React.memo(
height: `${size}px`, height: `${size}px`,
transform: `translateY(${start}px)`, transform: `translateY(${start}px)`,
}} }}
// biome-ignore lint/style/noNonNullAssertion: <exists>
onSelect={() => onChange(country.value!)} onSelect={() => onChange(country.value!)}
value={country.value} value={country.value}
> >

View file

@ -1,21 +1,21 @@
import { useTranslation } from "~/providers/I18nProvider"; import { ExternalLink } from "lucide-react";
import Link from "next/link";
import { useEffect, useState } from "react";
import { AnimatedNumber } from "~/components/custom_ui/animated-number";
import { LoadingPage } from "~/components/loading";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { import {
Card, Card,
CardContent,
CardDescription,
CardHeader, CardHeader,
CardTitle, CardTitle,
CardDescription,
CardContent,
} from "~/components/ui/card"; } from "~/components/ui/card";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs";
import { cn } from "~/lib/utils"; import { cn } from "~/lib/utils";
import { AnimatedNumber } from "~/components/custom_ui/animated-number"; import { useTranslation } from "~/providers/I18nProvider";
import { ExternalLink } from "lucide-react";
import { Tabs, TabsList, TabsTrigger, TabsContent } from "~/components/ui/tabs";
import Link from "next/link";
import { api } from "~/utils/api";
import { LoadingPage } from "~/components/loading";
import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum"; import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum";
import { useEffect, useState } from "react"; import { api } from "~/utils/api";
export const PricingChoice = () => { export const PricingChoice = () => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -185,7 +185,7 @@ export const PricingComponent = ({
Contratto Contratto
</h2> </h2>
{tipo == TipologiaPosizioneEnum.Transitorio ? ( {tipo === TipologiaPosizioneEnum.Transitorio ? (
<div className="flex flex-col justify-center leading-none"> <div className="flex flex-col justify-center leading-none">
<span <span
className="xs:text-3xl text-2xl font-semibold sm:text-6xl" className="xs:text-3xl text-2xl font-semibold sm:text-6xl"

View file

@ -36,7 +36,7 @@ export const ProgressRedirect = ({ href }: { href: string }) => {
await router.push(href); await router.push(href);
} }
if (progress == 100) { if (progress === 100) {
redirect().catch((error) => { redirect().catch((error) => {
console.error("Error during redirect:", error); console.error("Error during redirect:", error);
}); });

View file

@ -1,5 +1,3 @@
import { Confirm } from "~/components/confirm";
import { Button, buttonVariants } from "~/components/ui/button";
import { import {
Check, Check,
ChevronsUpDown, ChevronsUpDown,
@ -12,28 +10,16 @@ import {
Trash2, Trash2,
Wrench, Wrench,
} from "lucide-react"; } from "lucide-react";
import type { import Link from "next/link";
Storageindex, import { useRef, useState } from "react";
StorageindexId,
} from "~/schemas/public/Storageindex";
import { Label } from "~/components/ui/label";
import { UploadModal } from "~/components/upload_modal";
import { ExtIcon } from "~/components/area-riservata/allegati";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "~/components/ui/popover";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "~/components/ui/command";
import { api } from "~/utils/api";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
import { z } from "zod/v4";
import { ExtIcon } from "~/components/area-riservata/allegati";
import { Confirm } from "~/components/confirm";
import {
AnimatedButton,
type AnimatedButtonRef,
} from "~/components/custom_ui/animated-button";
import { import {
Credenza, Credenza,
CredenzaBody, CredenzaBody,
@ -46,11 +32,7 @@ import {
CredenzaTrigger, CredenzaTrigger,
} from "~/components/custom_ui/credenza"; } from "~/components/custom_ui/credenza";
import { LoadingPage } from "~/components/loading"; import { LoadingPage } from "~/components/loading";
import Link from "next/link"; import { Button, buttonVariants } from "~/components/ui/button";
import { cn, formatCurrency } from "~/lib/utils";
import { useRef, useState } from "react";
import { z } from "zod/v4";
import { Separator } from "~/components/ui/separator";
import { import {
Card, Card,
CardContent, CardContent,
@ -59,16 +41,34 @@ import {
CardHeader, CardHeader,
CardTitle, CardTitle,
} from "~/components/ui/card"; } from "~/components/ui/card";
import type { ServizioAnnunciUpdate } from "~/schemas/public/ServizioAnnunci";
import { Switch } from "~/components/ui/switch";
import { useServizio, useServizioAnnuncio } from "~/providers/ServizioProvider";
import { import {
AnimatedButton, Command,
type AnimatedButtonRef, CommandEmpty,
} from "~/components/custom_ui/animated-button"; CommandGroup,
import type { AnnunciId } from "~/schemas/public/Annunci"; CommandInput,
CommandItem,
CommandList,
} from "~/components/ui/command";
import { Label } from "~/components/ui/label";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "~/components/ui/popover";
import { Separator } from "~/components/ui/separator";
import { Switch } from "~/components/ui/switch";
import { UploadModal } from "~/components/upload_modal";
import { cn, formatCurrency } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider"; import { useTranslation } from "~/providers/I18nProvider";
import { useServizio, useServizioAnnuncio } from "~/providers/ServizioProvider";
import type { AnnunciId } from "~/schemas/public/Annunci";
import type { ServizioAnnunciUpdate } from "~/schemas/public/ServizioAnnunci";
import type {
Storageindex,
StorageindexId,
} from "~/schemas/public/Storageindex";
import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum"; import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum";
import { api } from "~/utils/api";
export const AnnuncioActions = () => { export const AnnuncioActions = () => {
const { servizioId, userId, isAdmin } = useServizio(); const { servizioId, userId, isAdmin } = useServizio();
@ -527,7 +527,7 @@ const ContrattoSection = ({
}; };
if (isLoading) return <LoadingPage />; if (isLoading) return <LoadingPage />;
if (files == undefined) { if (files === undefined) {
return <p>Errore nel caricamento dei documenti</p>; return <p>Errore nel caricamento dei documenti</p>;
} }
return ( return (
@ -619,7 +619,7 @@ const RicevutaSection = ({
}; };
if (isLoading) return <LoadingPage />; if (isLoading) return <LoadingPage />;
if (files == undefined) { if (files === undefined) {
return <p>Errore nel caricamento dei documenti</p>; return <p>Errore nel caricamento dei documenti</p>;
} }
return ( return (
@ -773,7 +773,7 @@ const DocSection = ({
}); });
if (isLoading) return <LoadingPage />; if (isLoading) return <LoadingPage />;
if (files == undefined) { if (files === undefined) {
return <p>Errore nel caricamento dei documenti</p>; return <p>Errore nel caricamento dei documenti</p>;
} }
return ( return (
@ -905,6 +905,7 @@ const DocCombo = ({
value={file.id} value={file.id}
onSelect={(currentValue) => { onSelect={(currentValue) => {
if (currentValue !== current) { if (currentValue !== current) {
// biome-ignore lint/style/noNonNullAssertion: <exists>
onSelect(files.find((f) => f.id === currentValue)!); onSelect(files.find((f) => f.id === currentValue)!);
} }
setOpen(false); setOpen(false);

View file

@ -1,14 +1,5 @@
import { useServizioAnnuncio } from "~/providers/ServizioProvider";
import { Interactions } from "~/components/servizio/interactions";
import type { Annunci } from "~/schemas/public/Annunci";
import { useTranslation } from "~/providers/I18nProvider";
import { cn, formatCurrency } from "~/lib/utils";
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
import { ImageFlbk } from "~/components/ImageWithFallback";
import { Button } from "~/components/ui/button";
import { ExternalLink, UnfoldVertical } from "lucide-react"; import { ExternalLink, UnfoldVertical } from "lucide-react";
import Link from "next/link"; import Link from "next/link";
import { handleConsegna } from "~/lib/annuncio_details";
import { import {
Credenza, Credenza,
CredenzaBody, CredenzaBody,
@ -20,6 +11,11 @@ import {
CredenzaTitle, CredenzaTitle,
CredenzaTrigger, CredenzaTrigger,
} from "~/components/custom_ui/credenza"; } from "~/components/custom_ui/credenza";
import { ImageFlbk } from "~/components/ImageWithFallback";
import { AnnuncioActions } from "~/components/servizio/annuncio_actions";
import { Interactions } from "~/components/servizio/interactions";
import { Button } from "~/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
import { import {
Carousel, Carousel,
CarouselContent, CarouselContent,
@ -27,7 +23,11 @@ import {
CarouselNext, CarouselNext,
CarouselPrevious, CarouselPrevious,
} from "~/components/ui/carousel"; } from "~/components/ui/carousel";
import { AnnuncioActions } from "~/components/servizio/annuncio_actions"; import { handleConsegna } from "~/lib/annuncio_details";
import { cn, formatCurrency } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider";
import { useServizioAnnuncio } from "~/providers/ServizioProvider";
import type { Annunci } from "~/schemas/public/Annunci";
export const AnnuncioCard = ({ className }: { className?: string }) => { export const AnnuncioCard = ({ className }: { className?: string }) => {
const { data } = useServizioAnnuncio(); const { data } = useServizioAnnuncio();
@ -193,8 +193,7 @@ const AnnuncioDettaglio = ({
<div className="flex flex-col gap-2 px-2"> <div className="flex flex-col gap-2 px-2">
<Carousel opts={{ loop: true }}> <Carousel opts={{ loop: true }}>
<CarouselContent> <CarouselContent>
{data.url_immagini && {data?.url_immagini?.map((img, idx) => (
data.url_immagini.map((img, idx) => (
<CarouselItem key={img}> <CarouselItem key={img}>
<ImageFlbk <ImageFlbk
alt={`${data.codice} - ${idx}`} alt={`${data.codice} - ${idx}`}

View file

@ -1,10 +1,10 @@
import type { StorageindexId } from "~/schemas/public/Storageindex";
import { api } from "~/utils/api";
import { LoadingPage } from "~/components/loading";
import { AllegatoIframe } from "~/components/allegato-iframe"; import { AllegatoIframe } from "~/components/allegato-iframe";
import { LoadingPage } from "~/components/loading";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { handleDownload } from "~/hooks/filesHooks"; import { handleDownload } from "~/hooks/filesHooks";
import { useTranslation } from "~/providers/I18nProvider"; import { useTranslation } from "~/providers/I18nProvider";
import type { StorageindexId } from "~/schemas/public/Storageindex";
import { api } from "~/utils/api";
export const FileSection = ({ storageId }: { storageId: StorageindexId }) => { export const FileSection = ({ storageId }: { storageId: StorageindexId }) => {
const { data: fileInfos, isLoading } = api.storage.getStorageFromId.useQuery({ const { data: fileInfos, isLoading } = api.storage.getStorageFromId.useQuery({

View file

@ -1,19 +1,3 @@
import Link from "next/link";
import { Button, type ButtonConfigs } from "~/components/ui/button";
import { useTranslation } from "~/providers/I18nProvider";
import { api } from "~/utils/api";
import toast from "react-hot-toast";
import {
Credenza,
CredenzaBody,
CredenzaClose,
CredenzaContent,
CredenzaDescription,
CredenzaFooter,
CredenzaHeader,
CredenzaTitle,
CredenzaTrigger,
} from "~/components/custom_ui/credenza";
import { import {
CircleCheck, CircleCheck,
CircleUser, CircleUser,
@ -26,19 +10,35 @@ import {
Pointer, Pointer,
TriangleAlert, TriangleAlert,
} from "lucide-react"; } from "lucide-react";
import Link from "next/link";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import toast from "react-hot-toast";
import {
Credenza,
CredenzaBody,
CredenzaClose,
CredenzaContent,
CredenzaDescription,
CredenzaFooter,
CredenzaHeader,
CredenzaTitle,
CredenzaTrigger,
} from "~/components/custom_ui/credenza";
import LoadingButton from "~/components/custom_ui/loading-button"; import LoadingButton from "~/components/custom_ui/loading-button";
import { LoadingPage } from "~/components/loading"; import { LoadingPage } from "~/components/loading";
import { useRouter } from "next/router"; import { Button, type ButtonConfigs } from "~/components/ui/button";
import { cn } from "~/lib/utils";
import { useEffect, useState } from "react";
import { useServizio, useServizioAnnuncio } from "~/providers/ServizioProvider";
import { import {
Tooltip, Tooltip,
TooltipContent, TooltipContent,
TooltipProvider, TooltipProvider,
TooltipTrigger, TooltipTrigger,
} from "~/components/ui/tooltip"; } from "~/components/ui/tooltip";
import { cn } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider";
import { useServizio, useServizioAnnuncio } from "~/providers/ServizioProvider";
import type { AnnunciId } from "~/schemas/public/Annunci"; import type { AnnunciId } from "~/schemas/public/Annunci";
import { api } from "~/utils/api";
export const Interactions = () => { export const Interactions = () => {
const { servizio, servizioId } = useServizio(); const { servizio, servizioId } = useServizio();

View file

@ -1,4 +1,21 @@
import type { UsersId } from "~/schemas/public/Users"; import { Package, PackageCheck, UserCircle } from "lucide-react";
import Link from "next/link";
import { useRouter } from "next/router";
import { useEffect } from "react";
import toast from "react-hot-toast";
import { AnnuncioCard } from "~/components/servizio/annuncio_card";
import { SaldoButton } from "~/components/servizio/interactions";
import { ServizioDuration } from "~/components/servizio/service-duration-display";
import {
ServizioActions,
ServizioActions2,
} from "~/components/servizio/servizio_actions";
import {
AnnunciCompatibili,
AnnunciInConferma,
AnnunciSelezionati,
} from "~/components/servizio/servizio_annunci_accordions";
import { Button } from "~/components/ui/button";
import { import {
Card, Card,
CardContent, CardContent,
@ -6,33 +23,16 @@ import {
CardHeader, CardHeader,
CardTitle, CardTitle,
} from "~/components/ui/card"; } from "~/components/ui/card";
import { cn } from "~/lib/utils";
import { Button } from "~/components/ui/button";
import type { ServizioData } from "~/server/controllers/servizio.controller";
import { Package, PackageCheck, UserCircle } from "lucide-react";
import Link from "next/link";
import { Progress } from "~/components/ui/progress"; import { Progress } from "~/components/ui/progress";
import { import { cn } from "~/lib/utils";
ServizioActions,
ServizioActions2,
} from "~/components/servizio/servizio_actions";
import { SaldoButton } from "~/components/servizio/interactions";
import { api } from "~/utils/api";
import { import {
ServizioAnnuncioProvider, ServizioAnnuncioProvider,
ServizioProvider, ServizioProvider,
useServizio, useServizio,
} from "~/providers/ServizioProvider"; } from "~/providers/ServizioProvider";
import { useRouter } from "next/router"; import type { UsersId } from "~/schemas/public/Users";
import { useEffect } from "react"; import type { ServizioData } from "~/server/controllers/servizio.controller";
import toast from "react-hot-toast"; import { api } from "~/utils/api";
import {
AnnunciCompatibili,
AnnunciInConferma,
AnnunciSelezionati,
} from "~/components/servizio/servizio_annunci_accordions";
import { AnnuncioCard } from "~/components/servizio/annuncio_card";
import { ServizioDuration } from "~/components/servizio/service-duration-display";
export const ServizioContainer = ({ export const ServizioContainer = ({
servizio, servizio,
@ -316,6 +316,7 @@ export const ServizioContent = () => {
> >
<h3> <h3>
{a.codice} - confermato il:{" "} {a.codice} - confermato il:{" "}
{/** biome-ignore lint/style/noNonNullAssertion: <already checked above> */}
{new Date(a.accettato_conferma_at!).toLocaleDateString( {new Date(a.accettato_conferma_at!).toLocaleDateString(
"it", "it",
{ {
@ -577,6 +578,7 @@ const ServizioMain = () => {
> >
<h3> <h3>
{a.codice} - confermato il:{" "} {a.codice} - confermato il:{" "}
{/** biome-ignore lint/style/noNonNullAssertion: <already checked> */}
{new Date(a.accettato_conferma_at!).toLocaleDateString( {new Date(a.accettato_conferma_at!).toLocaleDateString(
"it", "it",
{ {

View file

@ -1,13 +1,13 @@
import { Card, CardContent } from "~/components/ui/card";
import { CalendarDays, Hourglass, CalendarClock, Clock } from "lucide-react";
import { Progress } from "~/components/ui/progress"; // Import the Progress component
import { add, differenceInDays } from "date-fns"; import { add, differenceInDays } from "date-fns";
import { CalendarClock, CalendarDays, Clock, Hourglass } from "lucide-react";
import { import {
Accordion, Accordion,
AccordionContent, AccordionContent,
AccordionItem, AccordionItem,
AccordionTrigger, AccordionTrigger,
} from "~/components/ui/accordion"; } from "~/components/ui/accordion";
import { Card, CardContent } from "~/components/ui/card";
import { Progress } from "~/components/ui/progress"; // Import the Progress component
import { useMediaQuery } from "~/hooks/use-media-query"; import { useMediaQuery } from "~/hooks/use-media-query";
export const ServizioDuration = ({ export const ServizioDuration = ({

View file

@ -1,19 +1,18 @@
import toast from "react-hot-toast";
import type { AnnunciId } from "~/schemas/public/Annunci";
import { api } from "~/utils/api";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "~/components/ui/dialog";
import { Button } from "~/components/ui/button";
import { LoadingPage } from "~/components/loading";
import { MultiSelect } from "~/components/custom_ui/multiselect";
import { add } from "date-fns"; import { add } from "date-fns";
import { Bug, Calculator, ClockAlert, Plus, Wrench } from "lucide-react";
import { useState } from "react";
import toast from "react-hot-toast";
import {
Credenza,
CredenzaBody,
CredenzaContent,
CredenzaDescription,
CredenzaHeader,
CredenzaTitle,
CredenzaTrigger,
} from "~/components/custom_ui/credenza";
import { MultiSelect } from "~/components/custom_ui/multiselect";
import { LoadingPage } from "~/components/loading";
import { import {
AlertDialog, AlertDialog,
AlertDialogAction, AlertDialogAction,
@ -25,31 +24,31 @@ import {
AlertDialogTitle, AlertDialogTitle,
AlertDialogTrigger, AlertDialogTrigger,
} from "~/components/ui/alert-dialog"; } from "~/components/ui/alert-dialog";
import { Bug, Calculator, ClockAlert, Plus, Wrench } from "lucide-react"; import { Button } from "~/components/ui/button";
import { FormNewServizio, type FormValues } from "~/forms/FormNewServizio";
import {
Credenza,
CredenzaBody,
CredenzaContent,
CredenzaDescription,
CredenzaHeader,
CredenzaTitle,
CredenzaTrigger,
} from "~/components/custom_ui/credenza";
import { useState } from "react";
import { useServizio } from "~/providers/ServizioProvider";
import type { ServizioServizioId } from "~/schemas/public/Servizio";
import type { UsersId } from "~/schemas/public/Users";
import {
FormEditServizio,
type FormValues as EditFormValues,
} from "~/forms/FormEditServizioAdmin";
import { import {
Collapsible, Collapsible,
CollapsibleContent, CollapsibleContent,
CollapsibleTrigger, CollapsibleTrigger,
} from "~/components/ui/collapsible"; } from "~/components/ui/collapsible";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "~/components/ui/dialog";
import {
type FormValues as EditFormValues,
FormEditServizio,
} from "~/forms/FormEditServizioAdmin";
import { FormNewServizio, type FormValues } from "~/forms/FormNewServizio";
import { useServizio } from "~/providers/ServizioProvider";
import type { AnnunciId } from "~/schemas/public/Annunci";
import type { ServizioServizioId } from "~/schemas/public/Servizio";
import type { UsersId } from "~/schemas/public/Users";
import { api } from "~/utils/api";
export const ServizioActions = () => { export const ServizioActions = () => {
const { servizio, isAdmin, userId } = useServizio(); const { servizio, isAdmin, userId } = useServizio();
@ -411,7 +410,7 @@ const EditServizioAdmin = () => {
</CollapsibleTrigger> </CollapsibleTrigger>
<CollapsibleContent> <CollapsibleContent>
{(() => { {(() => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars // biome-ignore lint/correctness/noUnusedVariables: <need to extract>
const { annunci, ...rest } = servizio; const { annunci, ...rest } = servizio;
return <pre>{JSON.stringify(rest, null, 2)}</pre>; return <pre>{JSON.stringify(rest, null, 2)}</pre>;
})()} })()}

View file

@ -1,26 +1,26 @@
import { api } from "~/utils/api"; import { ExternalLink, Trash2 } from "lucide-react";
import Link from "next/link";
import toast from "react-hot-toast";
import { InteressatoButtonBatchV } from "~/components/annuncio-interactions/annuncio_interactions";
import { AddButton } from "~/components/servizio/annuncio_actions";
import {
AnnuncioCard,
BasicAnnuncioCard,
} from "~/components/servizio/annuncio_card";
import { import {
Accordion, Accordion,
AccordionContent, AccordionContent,
AccordionItem, AccordionItem,
AccordionTrigger, AccordionTrigger,
} from "~/components/ui/accordion"; } from "~/components/ui/accordion";
import type { UsersId } from "~/schemas/public/Users";
import {
AnnuncioCard,
BasicAnnuncioCard,
} from "~/components/servizio/annuncio_card";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { AddButton } from "~/components/servizio/annuncio_actions";
import { InteressatoButtonBatchV } from "~/components/annuncio-interactions/annuncio_interactions";
import { import {
ServizioAnnuncioProvider, ServizioAnnuncioProvider,
useServizio, useServizio,
} from "~/providers/ServizioProvider"; } from "~/providers/ServizioProvider";
import { ExternalLink, Trash2 } from "lucide-react"; import type { UsersId } from "~/schemas/public/Users";
import Link from "next/link";
import type { ServizioData } from "~/server/controllers/servizio.controller"; import type { ServizioData } from "~/server/controllers/servizio.controller";
import toast from "react-hot-toast"; import { api } from "~/utils/api";
export const AnnunciInConferma = ({ export const AnnunciInConferma = ({
annunci, annunci,
@ -118,7 +118,7 @@ export const AnnunciCompatibili = () => {
<Accordion <Accordion
type="single" type="single"
collapsible collapsible
defaultValue={!data || data.length == 0 ? "compatibili" : undefined} defaultValue={!data || data.length === 0 ? "compatibili" : undefined}
> >
<AccordionItem value="compatibili" className="space-y-4"> <AccordionItem value="compatibili" className="space-y-4">
<AccordionTrigger className="cursor-pointer rounded-md border-2 border-neutral-500 bg-white p-2"> <AccordionTrigger className="cursor-pointer rounded-md border-2 border-neutral-500 bg-white p-2">
@ -126,7 +126,7 @@ export const AnnunciCompatibili = () => {
</AccordionTrigger> </AccordionTrigger>
<AccordionContent> <AccordionContent>
<div className="flex flex-col flex-wrap gap-5"> <div className="flex flex-col flex-wrap gap-5">
{!data || data.length == 0 ? ( {!data || data.length === 0 ? (
<div className="flex items-center justify-center gap-1 rounded-md bg-white p-4 sm:flex"> <div className="flex items-center justify-center gap-1 rounded-md bg-white p-4 sm:flex">
<span> <span>
Nessun annuncio compatibile trovato. Amplia la ricerca per Nessun annuncio compatibile trovato. Amplia la ricerca per
@ -187,7 +187,7 @@ export const AnnunciRichiesti = ({ userId }: { userId: UsersId }) => {
</AccordionTrigger> </AccordionTrigger>
<AccordionContent> <AccordionContent>
<div className="flex flex-col flex-wrap gap-5"> <div className="flex flex-col flex-wrap gap-5">
{!data || data.length == 0 ? ( {!data || data.length === 0 ? (
<div className="flex items-center justify-center gap-1 rounded-md bg-white p-4 sm:flex"> <div className="flex items-center justify-center gap-1 rounded-md bg-white p-4 sm:flex">
<span> <span>
Nessun annuncio compatibile trovato. Amplia la ricerca per Nessun annuncio compatibile trovato. Amplia la ricerca per

View file

@ -26,6 +26,7 @@ export const LoadingSpinner = ({
strokeWidth="2" strokeWidth="2"
viewBox="0 0 24 24" viewBox="0 0 24 24"
> >
<title>spinner</title>
<path d="M21 12a9 9 0 1 1-6.219-8.56" /> <path d="M21 12a9 9 0 1 1-6.219-8.56" />
</svg> </svg>
); );

View file

@ -1,7 +1,7 @@
import Link from "next/link"; import Link from "next/link";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { useTranslation } from "~/providers/I18nProvider";
import { ShieldExclamationIcon } from "~/components/IconComponents"; import { ShieldExclamationIcon } from "~/components/IconComponents";
import { useTranslation } from "~/providers/I18nProvider";
export const Status500 = () => { export const Status500 = () => {
const router = useRouter(); const router = useRouter();
@ -16,6 +16,7 @@ export const Status500 = () => {
<p className="text-neutral-600">{t[500].sottotitolo}</p> <p className="text-neutral-600">{t[500].sottotitolo}</p>
<div className="flex flex-wrap items-center justify-center gap-3"> <div className="flex flex-wrap items-center justify-center gap-3">
<button <button
type="button"
onClick={() => { onClick={() => {
router.back(); router.back();
}} }}

View file

@ -8,6 +8,7 @@ export const HeroSvg = (props: SVGProps<SVGSVGElement>) => (
height={500} height={500}
width={500} width={500}
> >
<title>hero</title>
<path <path
d="m240.441 54.013-137.11 137.098V362.3h285.188V202.08L240.441 54.013Z" d="m240.441 54.013-137.11 137.098V362.3h285.188V202.08L240.441 54.013Z"
fill="#EAEAEA" fill="#EAEAEA"
@ -399,6 +400,7 @@ export const ASvg = (props: SVGProps<SVGSVGElement>) => (
viewBox="20 0 10 12" viewBox="20 0 10 12"
{...props} {...props}
> >
<title>{"\u0410"}</title>
<g <g
style={{ style={{
fill: "#E0211A", fill: "#E0211A",
@ -426,6 +428,7 @@ export const LogoSvg = (props: SVGProps<SVGSVGElement>) => (
viewBox="0 0 68.463 13.175" viewBox="0 0 68.463 13.175"
{...props} {...props}
> >
<title>{"lloggi.it Info"}</title>
<defs> <defs>
<path id="a" d="M69.953 191.276h677.665v225.16H69.953z" /> <path id="a" d="M69.953 191.276h677.665v225.16H69.953z" />
<path id="b" d="M69.953 191.276h677.665v225.16H69.953z" /> <path id="b" d="M69.953 191.276h677.665v225.16H69.953z" />
@ -506,6 +509,7 @@ export const EngFlag = (props: SVGProps<SVGSVGElement>) => (
viewBox="0 0 512 512" viewBox="0 0 512 512"
{...props} {...props}
> >
<title>EnglishFlag</title>
<path <path
d="M473.655 88.276H38.345C17.167 88.276 0 105.443 0 126.621V385.38c0 21.177 17.167 38.345 38.345 38.345h435.31c21.177 0 38.345-17.167 38.345-38.345V126.621c0-21.178-17.167-38.345-38.345-38.345z" d="M473.655 88.276H38.345C17.167 88.276 0 105.443 0 126.621V385.38c0 21.177 17.167 38.345 38.345 38.345h435.31c21.177 0 38.345-17.167 38.345-38.345V126.621c0-21.178-17.167-38.345-38.345-38.345z"
style={{ style={{
@ -540,6 +544,7 @@ export const ItaFlag = (props: SVGProps<SVGSVGElement>) => (
viewBox="0 0 512 512" viewBox="0 0 512 512"
{...props} {...props}
> >
<title>ItalianFlag</title>
<path <path
d="M38.345 88.273C17.167 88.273 0 105.44 0 126.618v258.759c0 21.177 17.167 38.345 38.345 38.345h132.322V88.273H38.345z" d="M38.345 88.273C17.167 88.273 0 105.44 0 126.618v258.759c0 21.177 17.167 38.345 38.345 38.345h132.322V88.273H38.345z"
style={{ style={{
@ -574,6 +579,7 @@ export const MissingFile = ({ className }: { className?: string }) => (
}} }}
className={className} className={className}
> >
<title>MissingFile</title>
<path <path
d="M152.5 31.5a79.737 79.737 0 0 1 21 1.5c1.929 3.256 2.429 6.756 1.5 10.5-.5 1.833-1.667 3-3.5 3.5-5.886-.04-11.553.96-17 3a14.442 14.442 0 0 0-2.5 5.5 59.854 59.854 0 0 1-2 14c-3.256 1.928-6.756 2.428-10.5 1.5-1.833-.5-3-1.667-3.5-3.5-4.35-16.87 1.15-28.87 16.5-36Z" d="M152.5 31.5a79.737 79.737 0 0 1 21 1.5c1.929 3.256 2.429 6.756 1.5 10.5-.5 1.833-1.667 3-3.5 3.5-5.886-.04-11.553.96-17 3a14.442 14.442 0 0 0-2.5 5.5 59.854 59.854 0 0 1-2 14c-3.256 1.928-6.756 2.428-10.5 1.5-1.833-.5-3-1.667-3.5-3.5-4.35-16.87 1.15-28.87 16.5-36Z"
style={{ style={{

View file

@ -1,13 +1,12 @@
import type { ColumnDef } from "@tanstack/react-table"; import type { ColumnDef } from "@tanstack/react-table";
import { DataTableColumnHeader } from "~/components/custom_ui/dataTable-header";
import { Button } from "~/components/ui/button";
import { Cog } from "lucide-react"; import { Cog } from "lucide-react";
import type { SearchFiltro } from "~/components/custom_ui/dataTable-toolbar";
import { DataTable } from "~/components/custom_ui/data-table";
import type { Annunci } from "~/schemas/public/Annunci";
import Link from "next/link"; import Link from "next/link";
import { DataTable } from "~/components/custom_ui/data-table";
import { DataTableColumnHeader } from "~/components/custom_ui/dataTable-header";
import type { SearchFiltro } from "~/components/custom_ui/dataTable-toolbar";
import { Button } from "~/components/ui/button";
import { StatusBadge } from "~/pages/area-riservata/admin/edit-annuncio/[id]"; import { StatusBadge } from "~/pages/area-riservata/admin/edit-annuncio/[id]";
import type { Annunci } from "~/schemas/public/Annunci";
export const AnnunciTable = ({ export const AnnunciTable = ({
data, data,
}: { }: {

View file

@ -1,7 +1,7 @@
import type { ColumnDef } from "@tanstack/react-table"; import type { ColumnDef } from "@tanstack/react-table";
import { DataTableColumnHeader } from "~/components/custom_ui/dataTable-header";
import { Cog } from "lucide-react"; import { Cog } from "lucide-react";
import { DataTable } from "~/components/custom_ui/data-table"; import { DataTable } from "~/components/custom_ui/data-table";
import { DataTableColumnHeader } from "~/components/custom_ui/dataTable-header";
import type { SearchFiltro } from "~/components/custom_ui/dataTable-toolbar"; import type { SearchFiltro } from "~/components/custom_ui/dataTable-toolbar";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import type { Banlist } from "~/schemas/public/Banlist"; import type { Banlist } from "~/schemas/public/Banlist";

View file

@ -1,7 +1,7 @@
import type { ColumnDef } from "@tanstack/react-table"; import type { ColumnDef } from "@tanstack/react-table";
import { DataTableColumnHeader } from "~/components/custom_ui/dataTable-header";
import { Cog } from "lucide-react"; import { Cog } from "lucide-react";
import { DataTable } from "~/components/custom_ui/data-table"; import { DataTable } from "~/components/custom_ui/data-table";
import { DataTableColumnHeader } from "~/components/custom_ui/dataTable-header";
import type { SearchFiltro } from "~/components/custom_ui/dataTable-toolbar"; import type { SearchFiltro } from "~/components/custom_ui/dataTable-toolbar";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import type { Banners } from "~/schemas/public/Banners"; import type { Banners } from "~/schemas/public/Banners";

Some files were not shown because too many files have changed in this diff Show more