diff --git a/app/resultados/page.tsx b/app/resultados/page.tsx
index 59dee1f..2a8b0b6 100644
--- a/app/resultados/page.tsx
+++ b/app/resultados/page.tsx
@@ -1,11 +1,10 @@
"use client";
-import { useState, useEffect } from "react";
+import { useState, useEffect, useCallback } from "react";
import { useSearchParams, useRouter } from "next/navigation";
import {
Search,
ArrowLeft,
Loader2,
- Filter,
Grid,
List,
SlidersHorizontal,
@@ -53,8 +52,7 @@ export default function ResultadosPage() {
try {
const country = await detectUserCountry(true);
setDetectedCountry(country.code);
- } catch (error) {
- console.warn("Erro ao detectar país:", error);
+ } catch {
setDetectedCountry("br");
}
};
@@ -62,88 +60,88 @@ export default function ResultadosPage() {
detectCountry();
}, []);
+ const loadProducts = useCallback(
+ async (pageNum: number) => {
+ try {
+ if (pageNum === 1) {
+ setLoading(true);
+ } else {
+ setLoadingMore(true);
+ }
+ setError(null);
+ setIsLoading(true);
+
+ const countryToUse = detectedCountry || countryParam || "br";
+
+ const result = await searchByName(query, countryToUse, pageNum, 20);
+
+ // Aplicar ordenação se especificada
+ let sortedProducts = result.products;
+ if (filters.sortBy) {
+ sortedProducts = sortProducts(
+ result.products,
+ filters.sortBy,
+ filters.sortOrder || "asc"
+ );
+ }
+
+ setProducts((prevProducts) =>
+ pageNum === 1 ? sortedProducts : [...prevProducts, ...sortedProducts]
+ );
+ setHasMore(result.products.length === 20);
+ setPage(pageNum);
+ setTotalResults(result.count || result.products.length);
+ } catch (err) {
+ setError(
+ err instanceof Error ? err.message : "Erro ao buscar produtos"
+ );
+ } finally {
+ setLoading(false);
+ setLoadingMore(false);
+ setIsLoading(false);
+ }
+ },
+ [
+ query,
+ detectedCountry,
+ countryParam,
+ filters.sortBy,
+ filters.sortOrder,
+ setIsLoading,
+ setTotalResults,
+ ]
+ );
+
useEffect(() => {
if (query) {
loadProducts(1);
}
- }, [query, countryParam, detectedCountry, filters]);
+ }, [query, countryParam, detectedCountry, loadProducts]);
- const loadProducts = async (pageNum: number) => {
- try {
- if (pageNum === 1) {
- setLoading(true);
- } else {
- setLoadingMore(true);
- }
- setError(null);
- setIsLoading(true);
-
- const countryToUse = detectedCountry || countryParam || "br";
-
- // Construir parâmetros de busca com filtros
- const searchParams = new URLSearchParams({
- q: query,
- country: countryToUse,
- page: pageNum.toString(),
- page_size: "20",
- });
-
- // Adicionar filtros à URL
- Object.entries(filters).forEach(([key, value]) => {
- if (value !== undefined && value !== null && value !== "") {
- if (Array.isArray(value)) {
- if (value.length > 0) {
- searchParams.set(key, value.join(","));
- }
- } else if (typeof value === "object" && value !== null) {
- Object.entries(value).forEach(([rangeKey, rangeValue]) => {
- if (rangeValue?.min !== undefined) {
- searchParams.set(`${rangeKey}_min`, rangeValue.min.toString());
- }
- if (rangeValue?.max !== undefined) {
- searchParams.set(`${rangeKey}_max`, rangeValue.max.toString());
- }
- });
- } else {
- searchParams.set(key, value.toString());
- }
- }
- });
-
- const result = await searchByName(query, countryToUse, pageNum, 20);
-
- // Aplicar ordenação se especificada
- let sortedProducts = result.products;
- if (filters.sortBy) {
- sortedProducts = sortProducts(
- result.products,
- filters.sortBy,
- filters.sortOrder || "asc"
- );
- }
-
- setProducts(
- pageNum === 1 ? sortedProducts : [...products, ...sortedProducts]
- );
- setHasMore(result.products.length === 20);
- setPage(pageNum);
- setTotalResults(result.count || result.products.length);
- } catch (err) {
- setError(err instanceof Error ? err.message : "Erro ao buscar produtos");
- } finally {
- setLoading(false);
- setLoadingMore(false);
- setIsLoading(false);
- }
- };
-
- const handleLoadMore = () => {
+ const handleLoadMore = useCallback(() => {
loadProducts(page + 1);
- };
+ }, [loadProducts, page]);
- const handleSortChange = (sortBy: string) => {
- updateFilters({ sortBy: sortBy as any });
- };
+ const handleSortChange = useCallback(
+ (sortBy: string) => {
+ updateFilters({
+ sortBy: sortBy as
+ | "relevance"
+ | "nutrition_grade"
+ | "name"
+ | "brand"
+ | "energy"
+ | "fat"
+ | "sugars"
+ | "completeness"
+ | "with_images"
+ | "with_nutrition"
+ | "eco_score"
+ | "nova_group",
+ });
+ },
+ [updateFilters]
+ );
if (!query) {
return (
@@ -181,7 +179,7 @@ export default function ResultadosPage() {
- Resultados para "{query}"
+ Resultados para "{query}"
{!loading && products.length > 0 && (
@@ -342,7 +340,7 @@ export default function ResultadosPage() {
{!loading && products.length > 0 && (
<>
diff --git a/components/ui/avatar.tsx b/components/ui/avatar.tsx
deleted file mode 100644
index 51e507b..0000000
--- a/components/ui/avatar.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-"use client"
-
-import * as React from "react"
-import * as AvatarPrimitive from "@radix-ui/react-avatar"
-
-import { cn } from "@/lib/utils"
-
-const Avatar = React.forwardRef<
- React.ElementRef
,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-Avatar.displayName = AvatarPrimitive.Root.displayName
-
-const AvatarImage = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-AvatarImage.displayName = AvatarPrimitive.Image.displayName
-
-const AvatarFallback = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
-
-export { Avatar, AvatarImage, AvatarFallback }
diff --git a/hooks/useProductFilters.ts b/hooks/useProductFilters.ts
index 6b0de23..db813a6 100644
--- a/hooks/useProductFilters.ts
+++ b/hooks/useProductFilters.ts
@@ -42,68 +42,75 @@ export function useProductFilters(options: UseProductFiltersOptions = {}) {
}
}, [filters, persistToLocalStorage, localStorageKey]);
- // Sincronizar filtros com URL
- useEffect(() => {
- const url = new URL(window.location.href);
- const currentParams = new URLSearchParams(url.search);
+ // Sincronizar filtros com URL (debounced)
+ const debouncedSyncURL = useCallback(
+ debounce((filters: ProductFilters) => {
+ const url = new URL(window.location.href);
+ const currentParams = new URLSearchParams(url.search);
- // Remover parâmetros de filtro existentes
- const filterParams = [
- "nutrition_grades",
- "nova_groups",
- "categories",
- "brands",
- "allergens",
- "exclude_allergens",
- "additives",
- "exclude_additives",
- "no_additives",
- "countries",
- "sort_by",
- "sort_order",
- "energy_min",
- "energy_max",
- "fat_min",
- "fat_max",
- "sugars_min",
- "sugars_max",
- "sodium_min",
- "sodium_max",
- ];
+ // Remover parâmetros de filtro existentes
+ const filterParams = [
+ "nutrition_grades",
+ "nova_groups",
+ "categories",
+ "brands",
+ "allergens",
+ "exclude_allergens",
+ "additives",
+ "exclude_additives",
+ "no_additives",
+ "countries",
+ "sort_by",
+ "sort_order",
+ "energy_min",
+ "energy_max",
+ "fat_min",
+ "fat_max",
+ "sugars_min",
+ "sugars_max",
+ "sodium_min",
+ "sodium_max",
+ ];
- filterParams.forEach((param) => {
- currentParams.delete(param);
- });
+ filterParams.forEach((param) => {
+ currentParams.delete(param);
+ });
- // Adicionar novos parâmetros de filtro
- Object.entries(filters).forEach(([key, value]) => {
- if (value !== undefined && value !== null && value !== "") {
- if (Array.isArray(value)) {
- if (value.length > 0) {
- currentParams.set(key, value.join(","));
+ // Adicionar novos parâmetros de filtro
+ Object.entries(filters).forEach(([key, value]) => {
+ if (value !== undefined && value !== null && value !== "") {
+ if (Array.isArray(value)) {
+ if (value.length > 0) {
+ currentParams.set(key, value.join(","));
+ }
+ } else if (typeof value === "object" && value !== null) {
+ // Para nutritionRanges
+ Object.entries(value).forEach(([rangeKey, rangeValue]) => {
+ if (rangeValue?.min !== undefined) {
+ currentParams.set(`${rangeKey}_min`, rangeValue.min.toString());
+ }
+ if (rangeValue?.max !== undefined) {
+ currentParams.set(`${rangeKey}_max`, rangeValue.max.toString());
+ }
+ });
+ } else {
+ currentParams.set(key, value.toString());
}
- } else if (typeof value === "object" && value !== null) {
- // Para nutritionRanges
- Object.entries(value).forEach(([rangeKey, rangeValue]) => {
- if (rangeValue?.min !== undefined) {
- currentParams.set(`${rangeKey}_min`, rangeValue.min.toString());
- }
- if (rangeValue?.max !== undefined) {
- currentParams.set(`${rangeKey}_max`, rangeValue.max.toString());
- }
- });
- } else {
- currentParams.set(key, value.toString());
}
- }
- });
+ });
- // Atualizar URL sem recarregar a página
- const newUrl = `${url.pathname}?${currentParams.toString()}`;
- if (newUrl !== window.location.pathname + window.location.search) {
- router.replace(newUrl, { scroll: false });
- }
- }, [filters, router]);
+ // Atualizar URL sem recarregar a página
+ const newUrl = `${url.pathname}?${currentParams.toString()}`;
+ if (newUrl !== window.location.pathname + window.location.search) {
+ router.replace(newUrl, { scroll: false });
+ }
+ }, 500),
+ [router]
+ );
+
+ useEffect(() => {
+ debouncedSyncURL(filters);
+ }, [filters, debouncedSyncURL]);
// Debounced update dos filtros
const debouncedUpdateFilters = useCallback(
diff --git a/lib/geolocation.ts b/lib/geolocation.ts
index 5034040..a6b16a6 100644
--- a/lib/geolocation.ts
+++ b/lib/geolocation.ts
@@ -10,7 +10,7 @@ interface CountryInfo {
// Cache para evitar múltiplas requisições
const CACHE_KEY = "nutriscan_user_country";
-const CACHE_DURATION = 24 * 60 * 60 * 1000; // 24 horas
+const CACHE_DURATION = 7 * 24 * 60 * 60 * 1000; // 7 dias
/**
* Verifica se o cache ainda é válido
diff --git a/lib/types.ts b/lib/types.ts
index eeb9fce..a7c01da 100644
--- a/lib/types.ts
+++ b/lib/types.ts
@@ -41,8 +41,16 @@ export interface ProductFilters {
| "brand"
| "energy"
| "fat"
- | "sugars";
+ | "sugars"
+ | "completeness"
+ | "with_images"
+ | "with_nutrition"
+ | "eco_score"
+ | "nova_group";
sortOrder?: "asc" | "desc";
+
+ // Assinatura de índice para compatibilidade
+ [key: string]: unknown;
}
export interface FilterOption {
diff --git a/next.config.mjs b/next.config.mjs
index 4678774..1676a6d 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -1,4 +1,57 @@
/** @type {import('next').NextConfig} */
-const nextConfig = {};
+const nextConfig = {
+ // Otimizações de performance
+ swcMinify: true,
+ compress: true,
+
+ // Configurações de imagens
+ images: {
+ remotePatterns: [
+ {
+ protocol: "https",
+ hostname: "static.openfoodfacts.org",
+ port: "",
+ pathname: "/images/products/**",
+ },
+ {
+ protocol: "https",
+ hostname: "images.openfoodfacts.org",
+ port: "",
+ pathname: "/images/products/**",
+ },
+ ],
+ formats: ["image/webp", "image/avif"],
+ deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
+ imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
+ },
+
+ // Headers de segurança e performance
+ async headers() {
+ return [
+ {
+ source: "/(.*)",
+ headers: [
+ {
+ key: "X-DNS-Prefetch-Control",
+ value: "on",
+ },
+ {
+ key: "X-Frame-Options",
+ value: "DENY",
+ },
+ {
+ key: "X-Content-Type-Options",
+ value: "nosniff",
+ },
+ ],
+ },
+ ];
+ },
+
+ // Otimizações de bundle
+ experimental: {
+ optimizeCss: true,
+ },
+};
export default nextConfig;
diff --git a/package.json b/package.json
index dae31bc..f70b876 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,6 @@
"@prisma/client": "^5.22.0",
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-alert-dialog": "^1.1.2",
- "@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-dialog": "^1.1.2",
"@radix-ui/react-dropdown-menu": "^2.1.2",
@@ -29,13 +28,11 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"framer-motion": "^11.12.0",
- "html5-qrcode": "^2.3.8",
"lucide-react": "^0.460.0",
"next": "14.2.18",
"next-themes": "^0.4.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
- "react-icons": "^5.5.0",
"tailwind-merge": "^2.5.5",
"tailwindcss-animate": "^1.0.7"
},
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 36137de..ac185f7 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -17,9 +17,6 @@ importers:
'@radix-ui/react-alert-dialog':
specifier: ^1.1.2
version: 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- '@radix-ui/react-avatar':
- specifier: ^1.1.10
- version: 1.1.10(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-checkbox':
specifier: ^1.3.3
version: 1.3.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -74,9 +71,6 @@ importers:
react-dom:
specifier: ^18.3.1
version: 18.3.1(react@18.3.1)
- react-icons:
- specifier: ^5.5.0
- version: 5.5.0(react@18.3.1)
tailwind-merge:
specifier: ^2.5.5
version: 2.5.5
@@ -377,19 +371,6 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-avatar@1.1.10':
- resolution: {integrity: sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
-
'@radix-ui/react-checkbox@1.3.3':
resolution: {integrity: sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==}
peerDependencies:
@@ -838,15 +819,6 @@ packages:
'@types/react':
optional: true
- '@radix-ui/react-use-is-hydrated@0.1.0':
- resolution: {integrity: sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==}
- peerDependencies:
- '@types/react': '*'
- react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
'@radix-ui/react-use-layout-effect@1.1.0':
resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==}
peerDependencies:
@@ -2193,11 +2165,6 @@ packages:
peerDependencies:
react: ^18.3.1
- react-icons@5.5.0:
- resolution: {integrity: sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==}
- peerDependencies:
- react: '*'
-
react-is@16.13.1:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
@@ -2526,11 +2493,6 @@ packages:
'@types/react':
optional: true
- use-sync-external-store@1.6.0:
- resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==}
- peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
-
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
@@ -2848,19 +2810,6 @@ snapshots:
'@types/react': 18.3.12
'@types/react-dom': 18.3.1
- '@radix-ui/react-avatar@1.1.10(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
- dependencies:
- '@radix-ui/react-context': 1.1.2(@types/react@18.3.12)(react@18.3.1)
- '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.12)(react@18.3.1)
- '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@18.3.12)(react@18.3.1)
- '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.12)(react@18.3.1)
- react: 18.3.1
- react-dom: 18.3.1(react@18.3.1)
- optionalDependencies:
- '@types/react': 18.3.12
- '@types/react-dom': 18.3.1
-
'@radix-ui/react-checkbox@1.3.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@radix-ui/primitive': 1.1.3
@@ -3311,13 +3260,6 @@ snapshots:
optionalDependencies:
'@types/react': 18.3.12
- '@radix-ui/react-use-is-hydrated@0.1.0(@types/react@18.3.12)(react@18.3.1)':
- dependencies:
- react: 18.3.1
- use-sync-external-store: 1.6.0(react@18.3.1)
- optionalDependencies:
- '@types/react': 18.3.12
-
'@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.3.12)(react@18.3.1)':
dependencies:
react: 18.3.1
@@ -3955,8 +3897,8 @@ snapshots:
'@typescript-eslint/parser': 8.16.0(eslint@8.57.1)(typescript@5.7.2)
eslint: 8.57.1
eslint-import-resolver-node: 0.3.9
- eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1)
- eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
+ eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1))(eslint@8.57.1)
+ eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1)
eslint-plugin-react: 7.37.2(eslint@8.57.1)
eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.1)
@@ -3975,37 +3917,37 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1):
+ eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1))(eslint@8.57.1):
dependencies:
'@nolyfill/is-core-module': 1.0.39
debug: 4.3.7
enhanced-resolve: 5.17.1
eslint: 8.57.1
- eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
+ eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
fast-glob: 3.3.2
get-tsconfig: 4.8.1
is-bun-module: 1.3.0
is-glob: 4.0.3
optionalDependencies:
- eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
+ eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
transitivePeerDependencies:
- '@typescript-eslint/parser'
- eslint-import-resolver-node
- eslint-import-resolver-webpack
- supports-color
- eslint-module-utils@2.12.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
+ eslint-module-utils@2.12.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 8.16.0(eslint@8.57.1)(typescript@5.7.2)
eslint: 8.57.1
eslint-import-resolver-node: 0.3.9
- eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1)
+ eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1))(eslint@8.57.1)
transitivePeerDependencies:
- supports-color
- eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
+ eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.8
@@ -4016,7 +3958,7 @@ snapshots:
doctrine: 2.1.0
eslint: 8.57.1
eslint-import-resolver-node: 0.3.9
- eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
+ eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.16.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
hasown: 2.0.2
is-core-module: 2.15.1
is-glob: 4.0.3
@@ -4834,10 +4776,6 @@ snapshots:
react: 18.3.1
scheduler: 0.23.2
- react-icons@5.5.0(react@18.3.1):
- dependencies:
- react: 18.3.1
-
react-is@16.13.1: {}
react-remove-scroll-bar@2.3.6(@types/react@18.3.12)(react@18.3.1):
@@ -5217,10 +5155,6 @@ snapshots:
optionalDependencies:
'@types/react': 18.3.12
- use-sync-external-store@1.6.0(react@18.3.1):
- dependencies:
- react: 18.3.1
-
util-deprecate@1.0.2: {}
which-boxed-primitive@1.0.2: