From f71cd167b3e5198d2df69a9af77eb035b6b895a0 Mon Sep 17 00:00:00 2001 From: evandrodevbr Date: Thu, 16 Jul 2026 16:31:50 -0300 Subject: [PATCH] feat: complete NutriScan redesign --- .eslintrc.cjs | 3 + .eslintrc.json | 3 - .gitignore | 8 +- .graphifyignore | 21 + app/api/products/[barcode]/route.ts | 4 +- app/components/CardList.tsx | 4 +- app/components/DeleteButton.tsx | 3 +- app/components/DonateCard.tsx | 207 +- app/components/FilterSidebar.tsx | 619 +- app/components/Footer.tsx | 193 +- app/components/IdInput.tsx | 35 +- app/components/ListaProductCard.tsx | 44 +- app/components/Main.tsx | 19 +- app/components/NutriScoreBadge.tsx | 248 +- app/components/NutritionBar.tsx | 368 +- app/components/ProductCard.tsx | 566 +- app/components/ProductSkeleton.tsx | 186 +- app/components/SearchBar.tsx | 102 +- app/components/header.tsx | 170 +- app/components/landing/DonationSection.tsx | 144 +- app/components/landing/Features.tsx | 214 +- app/components/landing/Hero.tsx | 349 +- app/components/landing/HowItWorks.tsx | 242 +- app/components/landing/PersuasiveCTA.tsx | 225 +- app/components/landing/TrustBadges.tsx | 78 +- app/globals.css | 654 +- app/layout.tsx | 43 +- app/lista/[id]/page.tsx | 22 +- app/page.tsx | 2 +- app/produto/[barcode]/page.tsx | 935 +- app/resultados/page.tsx | 1169 +- app/sobre/components/CTASection.tsx | 163 +- app/sobre/components/HeroSection.tsx | 130 +- app/sobre/components/HowItWorksSection.tsx | 162 +- app/sobre/components/ImpactSection.tsx | 209 +- app/sobre/components/MissionSection.tsx | 165 +- app/sobre/components/ProblemSection.tsx | 151 +- app/sobre/components/StorySection.tsx | 166 +- .../components/TargetAudienceSection.tsx | 185 +- app/sobre/components/ValuesSection.tsx | 208 +- app/sobre/page.tsx | 4 +- bun.lock | 2505 +++++ components/OptimizedImage.tsx | 17 +- data/products-cache.json | 7079 +++++++++++- design-handoff.tar.gz | 1 + docs/logo-prompts.md | 142 + docs/resedesign/NutriScan Redesign.html | 179 + docs/resedesign/design-full.png | Bin 0 -> 864339 bytes docs/resedesign/extract.js | 16 + docs/resedesign/extracted-template.html | 2549 +++++ graphify-out/.graphify_analysis.json | 529 + ...f4bfbabd17ee625ae06e05d507f541dc0ea7f.json | 1 + ...633908151c4f0c4e6836ac274783da77b5eed.json | 1 + ...16c94a83c0cd25e3109a2b3260697ce0bb52f.json | 1 + ...84d838b5d4ec4e829a9f50e77b875acb0261d.json | 1 + ...5f63508e09396d8a79ca57a2f5ad9faf027f6.json | 1 + ...1e3f38a012eeca97f96ba7a2b93c350ca33db.json | 1 + ...49e05b980e778be27b7cd5a60c6c576b207ce.json | 1 + ...747625b1bc36304e18d0f6de2ae28e514a7f7.json | 1 + ...d7205ee7c9263770f7846d790fc3255c94cd8.json | 1 + ...11d684c32594388090dd0c44ad4dc51fb3729.json | 1 + ...5277989fe6680b31cb77e99713ee44a5986fd.json | 1 + ...1ae15d493c0a9d44d0a332cb0c57fa9c93249.json | 1 + ...550e5ffb640dda435cc8147b6dec3f26db921.json | 1 + ...3ba027ebe33926c5186ae7f1c6b9cb9b1e00f.json | 1 + ...40300afa4a17a0dfc09e42a7dd8af6d1ce752.json | 1 + ...0004e1700b6a9756998fa75de2e920a372e1b.json | 1 + ...31112f98ed25556e22b132acd67939f03a441.json | 1 + ...508ac1af188e3bd0b2b7c3ffb0e01675d8d1e.json | 1 + ...cd01007ad536ed5d1099d5e02a4f2fb00da82.json | 1 + ...627f9e44c05cb53367372432f8fd26ef7518c.json | 1 + ...5cf346e62de6b91b39b3941aa0724cae21f74.json | 1 + ...f22fb13683dbeca4499d311678829820922bd.json | 1 + ...7610d8128ac94fd2698901ef9d15e9fb5b28f.json | 1 + ...2354a815fae2c6eb8c64371b3840ae02a7ab9.json | 1 + ...2172301d7b771504a19f6e7f7297bcccb7ad3.json | 1 + ...474a721ecf0dc869cbb9b68f43b042ed4a92c.json | 1 + ...e50eb9cd862d82e8acb21d9f3a2cbab7c5687.json | 1 + ...ce83379c93fdb492e0faaea08361e3c89b2a7.json | 1 + ...82bda405c7abe84831f8d7804798fd700b3de.json | 1 + ...6440a12af3e828174a1c8e2c979f239d34679.json | 1 + ...4148492d937dae5f706ab3cc271026cce3861.json | 1 + ...d38f09bf13c8d12414b3f33e49709f89d408a.json | 1 + ...501799e0b32bffc44a88e0703746465c361a6.json | 1 + ...da19c0b9c982831332cce75d4155d17ea77d8.json | 1 + ...7aab1f055f7ef3c25982ebea0da790d3bde2b.json | 1 + ...15ccc115c93e7349cea4288aa2fecf08d0833.json | 1 + ...a8943f83d7d9a6b4e0667b7d29f554200aa5d.json | 1 + ...288a3c696ed3f6b8fe912c115bfa7f96f9666.json | 1 + ...8bccf8ea7ec504979d80dad7b13273ebef020.json | 1 + ...39e4b06ed70e3cff8b4b75d751df7919f1830.json | 1 + ...4058c45e51dd34ba4ce5ca0cc3fbb5b9b6912.json | 1 + ...2772307e6ec8da94adaeade3f0167254f4418.json | 1 + ...b63a554709d9fe77c3712daf3cb9d6f708e93.json | 1 + ...ddebb3c872e2ac37bb723f31acbf8ffc9ae9a.json | 1 + ...3a8f2614ce59789f4ad12caa51513c7b997f5.json | 1 + ...20f5c9eb2489a6168dba7c01e470c302621f2.json | 1 + ...bf4f04451f1e73fe4f338734592111052944c.json | 1 + ...85ca138be46277f4ec9ece3f7f532c96c8f3e.json | 1 + ...ebd2844ec4972f69e43fec9b5e0d586d64a5c.json | 1 + ...db10acd7a9aa755b93eccf19097126656ebc4.json | 1 + ...2421746aeca9450f9f9dc67bbe322bd257774.json | 1 + ...49802e9ba0c4e117708f803749842759069e2.json | 1 + ...8b57cd992dfba03b2313def6f5de70634b780.json | 1 + ...9c4248f9afe6d8cab2217fb87f21309e4e9c0.json | 1 + ...dba9b81e2b9ce1de16b88fb52794de374d015.json | 1 + ...ff52a714505bc1fe84b8b8967c3fd5f00d718.json | 1 + ...d1a609ae2b7d4c3070b66565f66bd0caafe68.json | 1 + ...d41bd32df5edea799c91aa9f3f5ae7f45ece6.json | 1 + ...00600d67dff8f57a8f049e6c3c4837032cf86.json | 1 + ...eb99a8ad1c6495e8dacc1ac848c2edd90e089.json | 1 + ...b5f3083bd5b0d7f14d9df9998a618d6051b6a.json | 1 + ...3a24949b902b0976e055fdfd9d2b3c58b47bc.json | 1 + ...f493adc85e5fb01ec3d83c66c65a142a1c0be.json | 1 + ...b9fe9a68c8ee40edb65b6425ab2e629923a8c.json | 1 + ...3651100ee5e52d6bd5850c207f7eab1a62ea0.json | 1 + ...2f002e41d9d5ff88259751eff9979ebb27101.json | 1 + ...986f86e2eb0a5158e4b065b0ba819823815ff.json | 1 + ...50f08b6041eee1e5bcb1bde056432a8e2ea2f.json | 1 + ...517a96582f6e358cb69d831851f578d574b3b.json | 1 + ...ddc1fe3282693e2f1cd2ff5aafd305dcb50dc.json | 1 + ...eb8ca6e5c2639875a42b63c43f6fa6c2e1814.json | 1 + ...6245dd7093e07fc7f29460bf2023c971255f2.json | 1 + ...29282fed1fba6f28ab152cb2841f3284c0fe3.json | 1 + ...484c159351e2560d0f612562e2e452294a70e.json | 1 + ...77013fbc100cb02339e4e6feaa5bea83fde5e.json | 1 + ...37d22680d6a9b2f5fcfa72e24157ed9ccd4db.json | 1 + ...3cd8ecad56ec3a90b5d0de4812f1a067f697e.json | 1 + ...996534355060a9f6c4d9c7947376cf212b4e8.json | 1 + ...5c83794a32f91152bc6ade4c9f958c7c78899.json | 1 + ...b420ab2f72892ff3260e59035918aa354152f.json | 1 + ...7ebeb34f7b8751af28fd4af913a31a3a38bc0.json | 1 + ...0f12ab27d4c217d347f81b1a79b52bffccd05.json | 1 + ...6cc6b4de6e73046addf33e9b6e30fc202ba7a.json | 1 + ...ec202bd22d83dd049403e03d0ffe803116df3.json | 1 + ...aba4771d212ccafde21d10cad7d31248fd816.json | 1 + ...2bd8f16985282eb883f72916f94b3ab725ff9.json | 1 + ...e7e340bae15534f2eacdc504c4db19bc6ed67.json | 1 + ...25794507c3bac0ec7dda1fe6e62b7eede5151.json | 1 + ...06a1d4a0594451a97cb416be66b15f107910e.json | 1 + ...87ceaeee2ba3db8b7d3680002c7aeaca36fe0.json | 1 + ...c78d53ee1e4e765348ca914636b1c74896fc4.json | 1 + ...df3cb7da09e44ebe16bb8efd3cdebb5c87aeb.json | 1 + ...08fee3dc8854b7347d6dfa38208ee2ceaac55.json | 1 + ...b0a53b4414011096c28dfc4ca12fd31c95bfd.json | 1 + ...ce9bc5ef82b96b8b57de030d9fa38cf926d6d.json | 1 + ...6633e0e0cda41e626f16617433fb36ff5ceca.json | 1 + ...efa593a5210e3cb48b8960c179a850ba8cd77.json | 1 + graphify-out/graph.json | 9997 +++++++++++++++++ graphify-out/manifest.json | 454 + lib/jsonCacheManager.ts | 48 +- lib/openFoodFactsApi.ts | 14 +- next.config.mjs | 1 - null | 1 + package-lock.json | 7581 ------------- package.json | 57 +- pnpm-lock.yaml | 4920 ++++---- pnpm-workspace.yaml | 7 + public/images/CMJN-ICON_WHITE_BG_OFF.svg | 1 + public/images/logo-gemini.png | Bin 0 -> 12615 bytes public/images/logo-gemini.svg | 114 + tailwind.config.ts | 214 +- tsconfig.json | 25 +- 163 files changed, 30802 insertions(+), 14169 deletions(-) create mode 100644 .eslintrc.cjs delete mode 100644 .eslintrc.json create mode 100644 .graphifyignore create mode 100644 bun.lock create mode 100644 design-handoff.tar.gz create mode 100644 docs/logo-prompts.md create mode 100644 docs/resedesign/NutriScan Redesign.html create mode 100644 docs/resedesign/design-full.png create mode 100644 docs/resedesign/extract.js create mode 100644 docs/resedesign/extracted-template.html create mode 100644 graphify-out/.graphify_analysis.json create mode 100644 graphify-out/cache/ast/008ef0b5fde5c50ee69a8363744f4bfbabd17ee625ae06e05d507f541dc0ea7f.json create mode 100644 graphify-out/cache/ast/02ea83b4c70c2931ffa8c233831633908151c4f0c4e6836ac274783da77b5eed.json create mode 100644 graphify-out/cache/ast/02f68ee8843083d53b53831118a16c94a83c0cd25e3109a2b3260697ce0bb52f.json create mode 100644 graphify-out/cache/ast/050992d005034a6c15a4663830584d838b5d4ec4e829a9f50e77b875acb0261d.json create mode 100644 graphify-out/cache/ast/05e5502b415b6e6d38647c14bc45f63508e09396d8a79ca57a2f5ad9faf027f6.json create mode 100644 graphify-out/cache/ast/061e269ce36b2d8e8ff46be76da1e3f38a012eeca97f96ba7a2b93c350ca33db.json create mode 100644 graphify-out/cache/ast/064a244dfe9f2fca5157f6a7cbe49e05b980e778be27b7cd5a60c6c576b207ce.json create mode 100644 graphify-out/cache/ast/088c428dbc0af51c097f6d87a5c747625b1bc36304e18d0f6de2ae28e514a7f7.json create mode 100644 graphify-out/cache/ast/0a37976e80c3d547874db7d5993d7205ee7c9263770f7846d790fc3255c94cd8.json create mode 100644 graphify-out/cache/ast/0c281b0555d40e5d9f6f64fec4b11d684c32594388090dd0c44ad4dc51fb3729.json create mode 100644 graphify-out/cache/ast/12c38317169290ee69813853a895277989fe6680b31cb77e99713ee44a5986fd.json create mode 100644 graphify-out/cache/ast/14f800fedc18446845ec84fb4471ae15d493c0a9d44d0a332cb0c57fa9c93249.json create mode 100644 graphify-out/cache/ast/1aefd9bb7cdcc85a4912fb6002a550e5ffb640dda435cc8147b6dec3f26db921.json create mode 100644 graphify-out/cache/ast/1f0197a1094dd20e6f6b2d51b343ba027ebe33926c5186ae7f1c6b9cb9b1e00f.json create mode 100644 graphify-out/cache/ast/2381c3e9a46a1c0f6b28308670e40300afa4a17a0dfc09e42a7dd8af6d1ce752.json create mode 100644 graphify-out/cache/ast/24895657f66248c3ddfeadc292e0004e1700b6a9756998fa75de2e920a372e1b.json create mode 100644 graphify-out/cache/ast/2502936f134525c072dbc28292a31112f98ed25556e22b132acd67939f03a441.json create mode 100644 graphify-out/cache/ast/266df33ded4af00edf5c2f68586508ac1af188e3bd0b2b7c3ffb0e01675d8d1e.json create mode 100644 graphify-out/cache/ast/284b16abb50efea6ce4f447354ccd01007ad536ed5d1099d5e02a4f2fb00da82.json create mode 100644 graphify-out/cache/ast/2be70015943d756d18da2fc4a15627f9e44c05cb53367372432f8fd26ef7518c.json create mode 100644 graphify-out/cache/ast/3138e77cb6b9deb74402ea12fde5cf346e62de6b91b39b3941aa0724cae21f74.json create mode 100644 graphify-out/cache/ast/33374ac526b648b3ec4128f50d2f22fb13683dbeca4499d311678829820922bd.json create mode 100644 graphify-out/cache/ast/36d12d45babcc92799f33a0240a7610d8128ac94fd2698901ef9d15e9fb5b28f.json create mode 100644 graphify-out/cache/ast/396852224899726d54294bc496a2354a815fae2c6eb8c64371b3840ae02a7ab9.json create mode 100644 graphify-out/cache/ast/3994e03360e8251b96c2be1f0cf2172301d7b771504a19f6e7f7297bcccb7ad3.json create mode 100644 graphify-out/cache/ast/3bcbbe681f4a16e9bc9a26f5f5d474a721ecf0dc869cbb9b68f43b042ed4a92c.json create mode 100644 graphify-out/cache/ast/3d76f754d17690fe5bd9d69b15ae50eb9cd862d82e8acb21d9f3a2cbab7c5687.json create mode 100644 graphify-out/cache/ast/3e1f202df17478b45bd9d2335cfce83379c93fdb492e0faaea08361e3c89b2a7.json create mode 100644 graphify-out/cache/ast/44f517787136ef954babbf0550082bda405c7abe84831f8d7804798fd700b3de.json create mode 100644 graphify-out/cache/ast/44f6980e1d7819c9ffc7609e0b86440a12af3e828174a1c8e2c979f239d34679.json create mode 100644 graphify-out/cache/ast/456ab99d41ab71e48c2339685f34148492d937dae5f706ab3cc271026cce3861.json create mode 100644 graphify-out/cache/ast/49acfa12aa6d2190611dc5874b6d38f09bf13c8d12414b3f33e49709f89d408a.json create mode 100644 graphify-out/cache/ast/533e769ef643ff271d5fab611cc501799e0b32bffc44a88e0703746465c361a6.json create mode 100644 graphify-out/cache/ast/5543c4e0abfb95f535151ea9f3dda19c0b9c982831332cce75d4155d17ea77d8.json create mode 100644 graphify-out/cache/ast/58203679fb7f4052556ef2c480e7aab1f055f7ef3c25982ebea0da790d3bde2b.json create mode 100644 graphify-out/cache/ast/5cea92d81c21b5054c0c473880f15ccc115c93e7349cea4288aa2fecf08d0833.json create mode 100644 graphify-out/cache/ast/663af3eeb7225f5de0770d4bbb9a8943f83d7d9a6b4e0667b7d29f554200aa5d.json create mode 100644 graphify-out/cache/ast/67122e7bba7eb4e76f6247ccfb4288a3c696ed3f6b8fe912c115bfa7f96f9666.json create mode 100644 graphify-out/cache/ast/68b265cd8349d28b19e23e51acc8bccf8ea7ec504979d80dad7b13273ebef020.json create mode 100644 graphify-out/cache/ast/6bb43725ebfe943dbdf2c53d86539e4b06ed70e3cff8b4b75d751df7919f1830.json create mode 100644 graphify-out/cache/ast/6f2d315dbec7c30e23e67d8e19b4058c45e51dd34ba4ce5ca0cc3fbb5b9b6912.json create mode 100644 graphify-out/cache/ast/6fbed281fdc8efecc0990ed04052772307e6ec8da94adaeade3f0167254f4418.json create mode 100644 graphify-out/cache/ast/71e5da438e991da457988c5f127b63a554709d9fe77c3712daf3cb9d6f708e93.json create mode 100644 graphify-out/cache/ast/728e4838f83ef3b2104e81d1cc2ddebb3c872e2ac37bb723f31acbf8ffc9ae9a.json create mode 100644 graphify-out/cache/ast/7330e1ccc9ae563940319f27aeb3a8f2614ce59789f4ad12caa51513c7b997f5.json create mode 100644 graphify-out/cache/ast/74f7b6795bf956eff9c23ff5db920f5c9eb2489a6168dba7c01e470c302621f2.json create mode 100644 graphify-out/cache/ast/770ec76f43cdfa8309d600dd6ecbf4f04451f1e73fe4f338734592111052944c.json create mode 100644 graphify-out/cache/ast/7989b25e57feefc261f850b29bc85ca138be46277f4ec9ece3f7f532c96c8f3e.json create mode 100644 graphify-out/cache/ast/79c9c71bbf0f0f56cda98576f41ebd2844ec4972f69e43fec9b5e0d586d64a5c.json create mode 100644 graphify-out/cache/ast/7a7ac3a474baa899ad7ff6f0754db10acd7a9aa755b93eccf19097126656ebc4.json create mode 100644 graphify-out/cache/ast/7b28885c24413f18e5f1deabfec2421746aeca9450f9f9dc67bbe322bd257774.json create mode 100644 graphify-out/cache/ast/7c84cbb3d00368356d96be60c0449802e9ba0c4e117708f803749842759069e2.json create mode 100644 graphify-out/cache/ast/7ed84abdccc145edb747f6e8c268b57cd992dfba03b2313def6f5de70634b780.json create mode 100644 graphify-out/cache/ast/83b0ab06a9bef34c1711e4921d49c4248f9afe6d8cab2217fb87f21309e4e9c0.json create mode 100644 graphify-out/cache/ast/88f81548beb6c433c50b179a04bdba9b81e2b9ce1de16b88fb52794de374d015.json create mode 100644 graphify-out/cache/ast/9693de618c4a907d398c41ddec8ff52a714505bc1fe84b8b8967c3fd5f00d718.json create mode 100644 graphify-out/cache/ast/99dc8bee7773ece57739c9e77dfd1a609ae2b7d4c3070b66565f66bd0caafe68.json create mode 100644 graphify-out/cache/ast/9c8c56e913df4305ebf1c068373d41bd32df5edea799c91aa9f3f5ae7f45ece6.json create mode 100644 graphify-out/cache/ast/9d83bc9d3dab27c6d57ae5baa3b00600d67dff8f57a8f049e6c3c4837032cf86.json create mode 100644 graphify-out/cache/ast/9dd0d3ccd28b60f5c66f0bde1d6eb99a8ad1c6495e8dacc1ac848c2edd90e089.json create mode 100644 graphify-out/cache/ast/9f43d718f5496d5762258334cf0b5f3083bd5b0d7f14d9df9998a618d6051b6a.json create mode 100644 graphify-out/cache/ast/9fbe2359002d1e5635de7a838dc3a24949b902b0976e055fdfd9d2b3c58b47bc.json create mode 100644 graphify-out/cache/ast/a163ad5622417b37ef088c31cc5f493adc85e5fb01ec3d83c66c65a142a1c0be.json create mode 100644 graphify-out/cache/ast/a73c62935ec379f67d3c1ec9e0cb9fe9a68c8ee40edb65b6425ab2e629923a8c.json create mode 100644 graphify-out/cache/ast/aafaaf0a511f41e380d40d533863651100ee5e52d6bd5850c207f7eab1a62ea0.json create mode 100644 graphify-out/cache/ast/af04fa14e2d5de96c2d91b4eaef2f002e41d9d5ff88259751eff9979ebb27101.json create mode 100644 graphify-out/cache/ast/af9fa09a0d63c8a8df5d22d2421986f86e2eb0a5158e4b065b0ba819823815ff.json create mode 100644 graphify-out/cache/ast/b72d6cf41f2e779a9ed7d342a4250f08b6041eee1e5bcb1bde056432a8e2ea2f.json create mode 100644 graphify-out/cache/ast/b74b55cf63991ce06acb7814a58517a96582f6e358cb69d831851f578d574b3b.json create mode 100644 graphify-out/cache/ast/bb5accde59637d13cab1abbe688ddc1fe3282693e2f1cd2ff5aafd305dcb50dc.json create mode 100644 graphify-out/cache/ast/bf26b40066c76f26e9aaaf5ef80eb8ca6e5c2639875a42b63c43f6fa6c2e1814.json create mode 100644 graphify-out/cache/ast/c759f5b01b313d9f54b28f84f106245dd7093e07fc7f29460bf2023c971255f2.json create mode 100644 graphify-out/cache/ast/c95259fb557e95a2faac53433b329282fed1fba6f28ab152cb2841f3284c0fe3.json create mode 100644 graphify-out/cache/ast/ca346b1ba8fd861438280fa7dc7484c159351e2560d0f612562e2e452294a70e.json create mode 100644 graphify-out/cache/ast/ce25af8a8509578d105cd81f97377013fbc100cb02339e4e6feaa5bea83fde5e.json create mode 100644 graphify-out/cache/ast/ceef1bce770ee0df5e8312d03dd37d22680d6a9b2f5fcfa72e24157ed9ccd4db.json create mode 100644 graphify-out/cache/ast/d2f5eb04cb50a73c2487e61d8d23cd8ecad56ec3a90b5d0de4812f1a067f697e.json create mode 100644 graphify-out/cache/ast/d31654de61077f2c581325dd779996534355060a9f6c4d9c7947376cf212b4e8.json create mode 100644 graphify-out/cache/ast/d42f70494a64cb3fde1f8d768de5c83794a32f91152bc6ade4c9f958c7c78899.json create mode 100644 graphify-out/cache/ast/d74287c55145c28b11f2b324422b420ab2f72892ff3260e59035918aa354152f.json create mode 100644 graphify-out/cache/ast/d750e2139a415c2727f142021f77ebeb34f7b8751af28fd4af913a31a3a38bc0.json create mode 100644 graphify-out/cache/ast/dcf5ede886249006377bd94032d0f12ab27d4c217d347f81b1a79b52bffccd05.json create mode 100644 graphify-out/cache/ast/ddf22585a8fe8179f3ac29f850e6cc6b4de6e73046addf33e9b6e30fc202ba7a.json create mode 100644 graphify-out/cache/ast/e0731611af11d8d704a78032047ec202bd22d83dd049403e03d0ffe803116df3.json create mode 100644 graphify-out/cache/ast/e0b9f99bb826059d223c66743d0aba4771d212ccafde21d10cad7d31248fd816.json create mode 100644 graphify-out/cache/ast/ec1295799df273d24b3e1bb22602bd8f16985282eb883f72916f94b3ab725ff9.json create mode 100644 graphify-out/cache/ast/ee6e380e56715456a0d4019ddc8e7e340bae15534f2eacdc504c4db19bc6ed67.json create mode 100644 graphify-out/cache/ast/ef5b1be99c1de3a9d585a73095725794507c3bac0ec7dda1fe6e62b7eede5151.json create mode 100644 graphify-out/cache/ast/f24a7850d1e2f13f5d6f7a9c9eb06a1d4a0594451a97cb416be66b15f107910e.json create mode 100644 graphify-out/cache/ast/f2f4d307379dcfc2d689b06a79a87ceaeee2ba3db8b7d3680002c7aeaca36fe0.json create mode 100644 graphify-out/cache/ast/f6af76a9886841e71eea5b11660c78d53ee1e4e765348ca914636b1c74896fc4.json create mode 100644 graphify-out/cache/ast/f8b13bf7e887c46c9d856a60aabdf3cb7da09e44ebe16bb8efd3cdebb5c87aeb.json create mode 100644 graphify-out/cache/ast/f914300e7fa583c8fdeb4c73df908fee3dc8854b7347d6dfa38208ee2ceaac55.json create mode 100644 graphify-out/cache/ast/faa843987938c99cd4881c3ce50b0a53b4414011096c28dfc4ca12fd31c95bfd.json create mode 100644 graphify-out/cache/ast/fc962508ea6e8fa6dec6d9eda02ce9bc5ef82b96b8b57de030d9fa38cf926d6d.json create mode 100644 graphify-out/cache/ast/fec32829194692c71735477f2ba6633e0e0cda41e626f16617433fb36ff5ceca.json create mode 100644 graphify-out/cache/ast/ff07fb26966baaf528907e05c16efa593a5210e3cb48b8960c179a850ba8cd77.json create mode 100644 graphify-out/graph.json create mode 100644 graphify-out/manifest.json create mode 100644 null delete mode 100644 package-lock.json create mode 100644 public/images/CMJN-ICON_WHITE_BG_OFF.svg create mode 100644 public/images/logo-gemini.png create mode 100644 public/images/logo-gemini.svg diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..47c4db0 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,3 @@ +module.exports = { + extends: ["next/core-web-vitals", "next/typescript"], +}; diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 3722418..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": ["next/core-web-vitals", "next/typescript"] -} diff --git a/.gitignore b/.gitignore index 8547d02..d838331 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -<<<<<<< HEAD # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # dependencies @@ -40,7 +39,6 @@ next-env.d.ts #database /prisma/db /prisma/migrations -======= # Logs logs *.log @@ -171,4 +169,8 @@ dist .yarn/build-state.yml .yarn/install-state.gz .pnp.* ->>>>>>> ad0ba4c28c763a4748bd81d9039ccce4feab6b9e + +.env* +.flaskenv* +!.env.project +!.env.vault \ No newline at end of file diff --git a/.graphifyignore b/.graphifyignore new file mode 100644 index 0000000..d58fa88 --- /dev/null +++ b/.graphifyignore @@ -0,0 +1,21 @@ +node_modules/ +.next/ +dist/ +build/ +out/ +coverage/ +.git/ +.pnpm-store/ +.cache/ +*.log +.env +.env.* +__pycache__/ +*.pyc +.venv/ +venv/ +target/ +*.exe +*.dll +*.so +*.dylib diff --git a/app/api/products/[barcode]/route.ts b/app/api/products/[barcode]/route.ts index 48e3253..476d6f2 100644 --- a/app/api/products/[barcode]/route.ts +++ b/app/api/products/[barcode]/route.ts @@ -5,9 +5,9 @@ const USER_AGENT = "NutriScan/1.0 (https://nutriscan.com.br)"; export async function GET( request: NextRequest, - { params }: { params: { barcode: string } } + { params }: { params: Promise<{ barcode: string }> } ) { - const { barcode } = params; + const { barcode } = await params; const searchParams = request.nextUrl.searchParams; const cacheOnly = searchParams.get("cache_only") === "true"; diff --git a/app/components/CardList.tsx b/app/components/CardList.tsx index bd4e9ce..fe301d9 100644 --- a/app/components/CardList.tsx +++ b/app/components/CardList.tsx @@ -21,7 +21,7 @@ export async function CardList({ listaId }: CardListProps) { if (produtos.length === 0) { return ( -
+
Nenhum produto cadastrado ainda.
); @@ -47,7 +47,7 @@ export async function CardList({ listaId }: CardListProps) { {produtosComprados.length > 0 && (
-

+

Produtos Comprados

diff --git a/app/components/DeleteButton.tsx b/app/components/DeleteButton.tsx index 6776c84..14d5d93 100644 --- a/app/components/DeleteButton.tsx +++ b/app/components/DeleteButton.tsx @@ -42,7 +42,6 @@ export function DeleteButton({ produtoId, produtoNome, listaId }: DeleteButtonPr @@ -59,7 +58,7 @@ export function DeleteButton({ produtoId, produtoNome, listaId }: DeleteButtonPr Cancelar {isDeleting ? 'Excluindo...' : 'Excluir'} diff --git a/app/components/DonateCard.tsx b/app/components/DonateCard.tsx index a48eb8b..b184598 100644 --- a/app/components/DonateCard.tsx +++ b/app/components/DonateCard.tsx @@ -1,8 +1,7 @@ "use client"; -import { Card, CardContent } from "@/components/ui/card"; -import { Button } from "@/components/ui/button"; -import { Heart, Check, Code } from "lucide-react"; +import { Heart, Check } from "lucide-react"; +import { cn } from "@/lib/utils"; interface DonateCardProps { className?: string; @@ -10,141 +9,97 @@ interface DonateCardProps { } export function DonateCard({ className = "", variant = "default" }: DonateCardProps) { - // Layout mobile horizontal + /* ── Mobile horizontal ───────────────────────────────────────────────── */ if (variant === "mobile") { return ( - -
- {/* Ícone - tamanho ajustado */} -
- -
- - {/* Conteúdo - melhor espaçamento */} -
-
- {/* Título */} -

- Ajude o Projeto -

- - {/* Texto persuasivo */} -

- Mantenha este serviço gratuito e acessível para todos -

- - {/* Benefício rápido */} -
- - Qualquer valor faz diferença -
-
- - {/* Botão CTA - menor */} - - - +
+
+

+ Apoie o Projeto +

+

+ Mantenha o NutriScan gratuito e independente. +

+ + + Contribuir +
- + ); } - // Layout desktop padrão + /* ── Desktop card ────────────────────────────────────────────────────── */ return ( - - {/* Header com ícone animado */} -
-
- +
+ {/* Eyebrow */} + Apoie o Projeto + + {/* Headline */} +
+

+ Transparência alimentar,{" "} + para todos. +

+

+ O NutriScan opera sem anúncios e sem venda de dados. Sua + contribuição mantém o projeto vivo. +

- - {/* Overlay sutil */} -
- - {/* Badge de destaque */} -
-
- 💛 Apoie -
+ + {/* Benefits */} +
    + {[ + "Servidores sempre disponíveis", + "Novas funcionalidades", + "Acesso gratuito para todos", + ].map((item) => ( +
  • + + {item} +
  • + ))} +
+ + {/* CTA */} +
+ + + Contribuir agora + +

+ Qualquer valor ajuda +

- - - {/* Título principal */} -
-

- Apoie a Transparência Alimentar -

-

- Projeto mantido por um estudante dedicado -

-
- - {/* Benefícios */} -
-
- - Servidores sempre disponíveis -
-
- - Novas funcionalidades -
-
- - Acesso gratuito para todos -
-
- - {/* Mensagem humanizada */} -
-
- - - Desenvolvido com amor - -
-

- Cada doação ajuda a manter este projeto vivo e acessível -

-
- - {/* Botão CTA principal */} - - - - - {/* Texto de incentivo */} -

- Qualquer valor faz diferença 💛 -

-
- + ); } diff --git a/app/components/FilterSidebar.tsx b/app/components/FilterSidebar.tsx index f3de95b..2d8a513 100644 --- a/app/components/FilterSidebar.tsx +++ b/app/components/FilterSidebar.tsx @@ -120,106 +120,37 @@ export function FilterSidebar({ }); return ( -
- {/* Header */} -
-
- -

Filtros

+
+ + {/* ── Header ────────────────────────────────────────────────────────── */} +
+
+ + + Filtros avançados +
{hasActiveFilters && ( - + + Limpar tudo + )}
- {/* Resultados */} + {/* ── Result count ──────────────────────────────────────────────────── */} {totalResults > 0 && ( -
- {totalResults.toLocaleString()} produto{totalResults !== 1 ? "s" : ""}{" "} - encontrado{totalResults !== 1 ? "s" : ""} +
+ {totalResults.toLocaleString()} produto{totalResults !== 1 ? "s" : ""} encontrado{totalResults !== 1 ? "s" : ""}
)} - {/* Controles de Visualização e Cache */} -
- {/* Modo de Visualização */} - {onViewModeChange && ( -
-
Modo de visualização
-
- - -
-
- )} - - {/* Controles de Cache */} - {(onRefresh || onClearCache) && ( -
-
Controles
-
- {onRefresh && ( - - )} - {onClearCache && isCached && ( - - )} -
-
- )} -
- - {/* Filtros Ativos */} + {/* ── Active filter badges ───────────────────────────────────────────── */} {onRemoveFilter && hasActiveFilters && ( -
-
Filtros ativos
+
)} - - {/* Ordenação */} - - -
- - Ordenação -
-
- -
-
Ordenar por
- {onSortChange && ( - - )} -
-
-
+ {/* ── Cache / Refresh controls ──────────────────────────────────────── */} + {(onRefresh || onClearCache) && ( +
+ {onRefresh && ( + + )} + {onClearCache && isCached && ( + + )} +
+ )} - {/* Nutri-Score */} - - -
- - Classificação Nutricional -
-
- -
-
Nutri-Score
-
- {NUTRITION_GRADES.map((grade) => ( -
- - updateArrayFilter( - "nutritionGrades", - grade.grade, - checked as boolean - ) - } - /> - -
- ))} -
- - - -
- NOVA (Processamento) -
- - updateFilter( - "novaGroups", - value ? [parseInt(value) as 1 | 2 | 3 | 4] : [] - ) - } - className="space-y-2" + {/* ── View mode ─────────────────────────────────────────────────────── */} + {onViewModeChange && ( +
+
Visualização
+
+ {(["grid", "list"] as const).map((mode) => ( + + ))} +
+
+ )} + + {/* ── Accordion sections ────────────────────────────────────────────── */} + + + {/* Ordenação */} + {onSortChange && ( + + +
+ + Ordenação +
+
+ +
+ +
+
+
+ )} + + {/* Nutri-Score & NOVA */} + + +
+ + Classificação Nutricional +
+
+ +
+
+
Nutri-Score
+
+ {NUTRITION_GRADES.map((grade) => ( +
+ updateArrayFilter("nutritionGrades", grade.grade, checked as boolean)} + /> + +
+ ))} +
+
+ +
+ +
+
NOVA — Nível de processamento
+ updateFilter("novaGroups", value ? [parseInt(value) as 1 | 2 | 3 | 4] : [])} + className="space-y-2" + > + {NOVA_GROUPS.map((group) => ( +
+ + +
+ ))} +
+
{/* Categorias */} - + -
- - Categorias +
+ + Categorias
- -
+ +
setSearchCategories(e.target.value)} - className="h-8" + style={{ height: 34, fontSize: 13, borderColor: "var(--border-subtle, #e8e0d0)", background: "var(--bg-base, #f9f6f0)" }} /> -
+
{POPULAR_CATEGORIES_WITH_ICONS.filter( (cat) => - cat.label - .toLowerCase() - .includes(searchCategories.toLowerCase()) || - cat.value - .toLowerCase() - .includes(searchCategories.toLowerCase()) + cat.label.toLowerCase().includes(searchCategories.toLowerCase()) || + cat.value.toLowerCase().includes(searchCategories.toLowerCase()) ).map((category) => { - const IconComponent = LucideIcons[ - category.icon as keyof typeof LucideIcons - ] as React.ComponentType<{ className?: string }> | undefined; + const IconComponent = LucideIcons[category.icon as keyof typeof LucideIcons] as React.ComponentType<{ style?: React.CSSProperties }> | undefined; return ( -
+
- updateArrayFilter( - "categories", - category.value, - checked as boolean - ) - } + checked={filters.categories?.includes(category.value) || false} + onCheckedChange={(checked) => updateArrayFilter("categories", category.value, checked as boolean)} /> -
@@ -416,70 +319,53 @@ export function FilterSidebar({ {/* Marcas */} - + -
- - Marcas +
+ + Marcas
- -
+ +
setSearchBrands(e.target.value)} - className="h-8" + style={{ height: 34, fontSize: 13, borderColor: "var(--border-subtle, #e8e0d0)", background: "var(--bg-base, #f9f6f0)" }} /> -
- Digite o nome da marca para buscar -
+
Digite para filtrar por marca
{/* Alérgenos */} - + -
- - Alérgenos +
+ + Alérgenos
- -
+ +
setSearchAllergens(e.target.value)} - className="h-8" + style={{ height: 34, fontSize: 13, borderColor: "var(--border-subtle, #e8e0d0)", background: "var(--bg-base, #f9f6f0)" }} /> -
+
{COMMON_ALLERGENS.filter((allergen) => allergen.toLowerCase().includes(searchAllergens.toLowerCase()) ).map((allergen) => ( -
+
- updateArrayFilter( - "allergens", - allergen, - checked as boolean - ) - } + onCheckedChange={(checked) => updateArrayFilter("allergens", allergen, checked as boolean)} /> -
@@ -490,32 +376,26 @@ export function FilterSidebar({ {/* Aditivos */} - + -
- - Aditivos +
+ + Aditivos
- -
-
-