From 084cf9288c37b15fa765fa4df7dbe43d462f45fe Mon Sep 17 00:00:00 2001 From: Lucas Menezes Date: Sun, 1 Dec 2024 09:11:37 -0300 Subject: [PATCH] v0.1.1 --- .vscode/settings.json | 3 + README.md | 4 +- app/[locale]/about/page.tsx | 66 +- app/[locale]/community/page.tsx | 63 +- app/[locale]/globals.css | 74 +- app/[locale]/layout.tsx | 26 +- app/[locale]/page.tsx | 28 +- app/[locale]/privacy/page.tsx | 23 +- app/[locale]/search/[category]/page.tsx | 47 + app/[locale]/terms/page.tsx | 2 +- components/Alert/Alert.module.css | 14 +- components/Banner/Banner.module.css | 73 +- components/Banner/index.tsx | 38 +- components/BlurBall/BlurBall.module.css | 21 + .../index.tsx} | 30 +- components/Button/Button.module.css | 23 +- components/Button/index.tsx | 31 +- .../ButtonGeolocation.module.css | 15 +- components/CardsFeat/CardsFeat.module.css | 53 +- components/CardsFeat/index.tsx | 85 +- components/CardsLink/CardsLink.module.css | 21 +- components/CardsLink/index.tsx | 22 +- .../CookiesPopup/CookiesPopup.module.css | 31 +- components/CookiesPopup/index.tsx | 11 +- components/Footer/Footer.module.css | 42 +- components/Footer/index.tsx | 88 +- .../GradientComponent.module.css | 30 + components/GradientComponent/index.tsx | 17 + components/Header/Header.module.css | 268 +- components/Header/index.tsx | 401 +-- components/Search/Search.module.css | 264 +- components/Search/index.tsx | 334 +- components/SearchNav/SearchNav.module.css | 95 + components/SearchNav/index.tsx | 109 + .../SearchOptions/SearchOptions.module.css | 17 + components/SearchOptions/index.tsx | 53 + .../SearchSuggestions.module.css | 17 +- components/SearchSuggestions/index.tsx | 20 +- components/SearchTitle/SearchTitle.module.css | 55 +- components/SearchTitle/index.tsx | 46 +- components/SearchVoice/SearchVoice.module.css | 16 +- components/Select/Select.module.css | 8 +- components/Select/index.tsx | 12 +- components/SelectLanguage/index.tsx | 38 +- components/SvgIcons/index.tsx | 513 ++- components/SvgIllustrations/index.tsx | 4 +- components/SvgLogo.tsx | 9 +- components/Welcome/Welcome.module.css | 21 + components/Welcome/index.tsx | 21 + components/WidgetFeed/WidgetFeed.module.css | 172 + components/WidgetFeed/index.tsx | 158 + .../WidgetTrends/WidgetTrends.module.css | 180 +- components/WidgetTrends/index.tsx | 50 +- .../WidgetVideoStories.module.css | 126 +- components/WidgetVideoStories/index.tsx | 64 +- contexts/SearchContext.tsx | 54 +- i18n.ts | 2 +- interfaces/search.ts | 5 + layouts/AppLayout/AppLayout.module.css | 8 - layouts/AppLayout/index.tsx | 28 +- .../WebsiteLayout/WebsiteLayout.module.css | 45 +- layouts/WebsiteLayout/index.tsx | 2 +- locales/en.json | 574 +++- locales/pt-BR.json | 1773 +++++++---- locales/zh-CN.json | 209 ++ middleware.ts | 2 +- next.config.js | 10 + package-lock.json | 2825 ++++++++++------- package.json | 3 + pages/api/trends/academic.ts | 11 +- pages/api/trends/games.ts | 45 + pages/api/trends/legal.ts | 84 +- pages/api/trends/local.ts | 4 +- pages/api/trends/news.ts | 2 +- pages/api/trends/shopping.ts | 117 +- public/apple-touch-icon.png | Bin 8088 -> 10737 bytes public/favicon-color.ico | Bin 15406 -> 0 bytes public/favicon.ico | Bin 15406 -> 15406 bytes public/findto-sparkle-old.svg | 1 + public/findto-sparkle.svg | 4 +- public/fonts/font-medium.woff2 | Bin 0 -> 15608 bytes public/icon-1024x1024-maskable.png | Bin 468241 -> 449000 bytes public/icon-1024x1024.png | Bin 36821 -> 39195 bytes public/icon-192x192-maskable.png | Bin 6405 -> 9243 bytes public/icon-192x192.png | Bin 5977 -> 8328 bytes public/icon-512x512-maskable.png | Bin 58728 -> 105192 bytes public/icon-512x512.png | Bin 19151 -> 29543 bytes public/icon.svg | 2 +- public/images/logos/1337x.svg | 7 +- public/images/logos/99freelas.svg | 7 +- public/images/logos/Infojobs.svg | 16 +- public/images/logos/academia.svg | 7 +- public/images/logos/adobe-firefly.svg | 33 +- public/images/logos/adobe-stock.svg | 9 +- public/images/logos/adzuna.svg | 7 +- public/images/logos/afp.svg | 30 +- public/images/logos/agencia-brasil.svg | 13 +- public/images/logos/airbnb.svg | 48 +- public/images/logos/aliexpress.svg | 44 +- public/images/logos/aljazeera.svg | 18 +- public/images/logos/alternativeto.svg | 20 +- public/images/logos/amazon-music.svg | 7 +- public/images/logos/amazon.svg | 16 +- public/images/logos/americanas.svg | 9 +- public/images/logos/app-store.svg | 7 +- public/images/logos/apple-maps.svg | 7 +- public/images/logos/apple-music.svg | 32 +- public/images/logos/apple-tv+.svg | 13 +- public/images/logos/apple-vision-pro.svg | 6 + public/images/logos/arxiv.svg | 11 +- public/images/logos/audius.svg | 14 +- public/images/logos/baidu.svg | 19 +- public/images/logos/banco-central.svg | 11 +- public/images/logos/bandcamp.svg | 9 +- public/images/logos/base.svg | 25 +- public/images/logos/behance.svg | 62 +- public/images/logos/bibliotecas-publicas.svg | 34 + public/images/logos/bing-travel.svg | 23 +- public/images/logos/bing.svg | 7 +- public/images/logos/bitbucket.svg | 9 +- public/images/logos/bloomberg.svg | 7 +- public/images/logos/bluesky.svg | 22 +- public/images/logos/bne.svg | 12 +- public/images/logos/booking.svg | 14 +- public/images/logos/boticario.svg | 10 +- public/images/logos/brave.svg | 9 +- public/images/logos/canva.svg | 53 + public/images/logos/carrefour.svg | 12 +- public/images/logos/carta.svg | 7 - public/images/logos/cartacapital.svg | 8 + public/images/logos/casas-bahia.svg | 35 +- public/images/logos/catho.svg | 7 +- public/images/logos/centauro.svg | 16 +- public/images/logos/chrome-web-store.svg | 10 +- public/images/logos/claro-tv+.svg | 14 + public/images/logos/claude.svg | 10 +- public/images/logos/codepen.svg | 15 +- public/images/logos/concursos-brasil.svg | 1 - public/images/logos/concursos-no-brasil.svg | 16 + public/images/logos/congresso-nacional.svg | 14 +- public/images/logos/copilot.svg | 33 +- public/images/logos/core.svg | 23 +- public/images/logos/crates.svg | 10 +- public/images/logos/crunchyroll.svg | 17 +- public/images/logos/dailymotion.svg | 7 +- public/images/logos/dazn.svg | 6 + public/images/logos/deezer.svg | 11 +- public/images/logos/deviantart.svg | 31 +- public/images/logos/discogs.svg | 17 +- public/images/logos/discord.svg | 11 +- public/images/logos/disney+.svg | 11 +- public/images/logos/docker-hub.svg | 7 +- public/images/logos/douyin.svg | 6 + public/images/logos/dribbble.svg | 9 +- public/images/logos/duckduckgo.svg | 11 +- public/images/logos/ea.svg | 8 + public/images/logos/economist.svg | 20 +- public/images/logos/ecosia.svg | 18 +- public/images/logos/empregos.svg | 16 + public/images/logos/enjoei.svg | 10 +- public/images/logos/epic-games.svg | 9 + public/images/logos/escavador.svg | 9 +- public/images/logos/estadao.svg | 9 +- public/images/logos/eventbrite.svg | 13 +- public/images/logos/eventim.svg | 28 +- public/images/logos/exame.svg | 9 + public/images/logos/expedia.svg | 18 + public/images/logos/fandango.svg | 33 +- public/images/logos/firefox-addons.svg | 7 +- public/images/logos/fiverr.svg | 15 +- public/images/logos/flathub.svg | 14 +- public/images/logos/flickr.svg | 20 +- public/images/logos/flipboard.svg | 9 +- public/images/logos/folha.svg | 7 +- public/images/logos/forbes.svg | 42 +- public/images/logos/foursquare.svg | 39 - public/images/logos/freepik.svg | 20 +- public/images/logos/galaxy-store.svg | 47 + public/images/logos/game-jolt.svg | 6 + public/images/logos/gemini.svg | 32 +- public/images/logos/genius.svg | 11 +- public/images/logos/getty-images.svg | 3 +- public/images/logos/gibiru.svg | 9 +- public/images/logos/giphy.svg | 26 +- public/images/logos/github.svg | 17 +- public/images/logos/gitlab.svg | 11 +- public/images/logos/glassdoor.svg | 7 +- public/images/logos/glitch.svg | 16 +- public/images/logos/globo.svg | 1 - public/images/logos/globocom.svg | 12 + public/images/logos/globoplay.svg | 28 +- public/images/logos/gog.svg | 6 + public/images/logos/google-finance.svg | 11 + public/images/logos/google-maps.svg | 17 +- public/images/logos/google-news.svg | 18 +- public/images/logos/google-play.svg | 7 +- public/images/logos/google-scholar.svg | 11 +- public/images/logos/google.svg | 19 +- public/images/logos/govbr.svg | 16 +- public/images/logos/guardian.svg | 37 +- public/images/logos/gupy.svg | 10 +- public/images/logos/here-wego.svg | 19 +- public/images/logos/huawei-appgallery.svg | 7 + public/images/logos/hype-machine.svg | 12 +- public/images/logos/iask.svg | 11 + public/images/logos/ifood.svg | 9 +- public/images/logos/igdb.svg | 14 + public/images/logos/ign.svg | 14 + public/images/logos/iheart.svg | 7 +- public/images/logos/imgur.svg | 34 +- public/images/logos/indeed.svg | 17 +- public/images/logos/indiegogo.svg | 22 +- public/images/logos/info.svg | 47 +- public/images/logos/ingresso.svg | 39 +- public/images/logos/internet-archive.svg | 62 +- public/images/logos/itch.svg | 1 + public/images/logos/jooble.svg | 9 +- public/images/logos/jstor.svg | 23 +- public/images/logos/jusbrasil.svg | 11 +- public/images/logos/justica-eleitoral.svg | 13 +- public/images/logos/justica-federal.svg | 66 + public/images/logos/justwatch.svg | 4 + public/images/logos/kaggle.svg | 12 +- public/images/logos/kayak.svg | 12 +- public/images/logos/kickstarter.svg | 47 +- public/images/logos/kwai.svg | 12 + public/images/logos/lastfm.svg | 7 +- public/images/logos/letras.svg | 10 +- public/images/logos/letterboxd.svg | 75 +- public/images/logos/libreflix.svg | 10 +- public/images/logos/linkedin.svg | 9 +- public/images/logos/looke.svg | 22 + public/images/logos/mapquest.svg | 15 +- public/images/logos/mastodon.svg | 12 +- public/images/logos/medium.svg | 7 +- public/images/logos/meetup.svg | 49 +- public/images/logos/mendeley.svg | 18 +- public/images/logos/mercado-livre.svg | 14 +- public/images/logos/meta-ai.svg | 21 +- public/images/logos/meta-quest.svg | 4 + public/images/logos/metropoles.svg | 16 + public/images/logos/mistral.svg | 1 + public/images/logos/mobills.svg | 6 + public/images/logos/mojeek.svg | 7 +- public/images/logos/moovit.svg | 42 +- public/images/logos/mubi.svg | 15 +- public/images/logos/musixmatch.svg | 7 +- public/images/logos/myspace.svg | 24 +- public/images/logos/natura.svg | 9 +- public/images/logos/netflix.svg | 41 +- public/images/logos/netshoes.svg | 9 +- public/images/logos/newsweek.svg | 10 + public/images/logos/nexo.svg | 10 +- public/images/logos/nintendo.svg | 14 +- public/images/logos/npm.svg | 7 +- public/images/logos/nubank.svg | 1 + public/images/logos/nuget.svg | 18 +- public/images/logos/nuuvem.svg | 8 + public/images/logos/oasisbr.svg | 15 +- public/images/logos/openverse.svg | 16 +- public/images/logos/orcid.svg | 7 +- public/images/logos/packagist.svg | 19 +- public/images/logos/palco-mp3.svg | 31 + public/images/logos/pandora.svg | 45 +- public/images/logos/paramount+.svg | 22 +- public/images/logos/passei-direto.svg | 18 +- public/images/logos/pelando.svg | 9 +- public/images/logos/periodicos.svg | 22 +- public/images/logos/perplexity.svg | 7 +- public/images/logos/pexels.svg | 10 +- public/images/logos/phind.svg | 7 +- public/images/logos/pinterest.svg | 17 +- public/images/logos/pixabay.svg | 26 +- public/images/logos/playplus.svg | 12 + public/images/logos/playstation.svg | 6 + public/images/logos/plex.svg | 7 +- public/images/logos/plos-one.svg | 28 +- public/images/logos/pocket.svg | 9 +- public/images/logos/poder360.svg | 10 +- public/images/logos/presearch.svg | 10 +- public/images/logos/prime-video.svg | 7 +- public/images/logos/product-hunt.svg | 10 +- public/images/logos/project-gutenberg.svg | 15 + public/images/logos/pubdev.svg | 21 +- public/images/logos/pubmed.svg | 14 + public/images/logos/pypi.svg | 36 +- public/images/logos/quora.svg | 32 +- public/images/logos/qwant.svg | 10 +- public/images/logos/rappi.svg | 9 +- public/images/logos/rarbg.svg | 9 +- public/images/logos/rawg.svg | 12 + public/images/logos/reclame-aqui.svg | 11 + public/images/logos/reddit.svg | 11 +- public/images/logos/renner.svg | 9 +- public/images/logos/researchgate.svg | 12 +- public/images/logos/reuters.svg | 13 +- public/images/logos/sbt+.svg | 25 + public/images/logos/sciencedirect.svg | 7 +- public/images/logos/scopus.svg | 7 +- public/images/logos/searchcode.svg | 10 +- public/images/logos/searxng.svg | 11 +- public/images/logos/shein.svg | 9 +- public/images/logos/shopee.svg | 11 +- public/images/logos/shutterstock.svg | 29 +- public/images/logos/skyscanner.svg | 16 +- public/images/logos/smugmug.svg | 55 +- public/images/logos/softonic.svg | 11 +- public/images/logos/soundcloud.svg | 24 +- public/images/logos/sourceforge.svg | 52 +- public/images/logos/sourcegraph.svg | 11 +- public/images/logos/spotify.svg | 24 +- public/images/logos/springer.svg | 23 +- public/images/logos/stack-overflow.svg | 16 +- public/images/logos/startpage.svg | 14 +- public/images/logos/steam.svg | 15 +- public/images/logos/stf.svg | 1 - public/images/logos/sucupira.svg | 11 + public/images/logos/swisscows.svg | 11 +- public/images/logos/sympla.svg | 25 +- public/images/logos/talent.svg | 16 +- public/images/logos/temu.svg | 14 + public/images/logos/tensorflow.svg | 8 +- public/images/logos/terra.svg | 16 + public/images/logos/the-pirate-bay.svg | 24 +- public/images/logos/ticket360.svg | 26 +- public/images/logos/tidal.svg | 9 +- public/images/logos/tiktok.svg | 7 +- public/images/logos/time.svg | 14 + public/images/logos/trabalha-brasil.svg | 11 +- public/images/logos/trampos.svg | 13 +- public/images/logos/tribunais-superiores.svg | 13 + public/images/logos/tripadvisor.svg | 14 +- public/images/logos/tumblr.svg | 14 +- public/images/logos/tunein.svg | 45 +- public/images/logos/twitch.svg | 23 +- public/images/logos/ubisoft.svg | 14 + public/images/logos/unsplash.svg | 10 +- public/images/logos/uol-2.svg | 1 + public/images/logos/uol.svg | 23 +- public/images/logos/upwork.svg | 10 +- public/images/logos/vagalume.svg | 18 +- public/images/logos/vagas.svg | 7 +- public/images/logos/valor.svg | 14 + public/images/logos/vimeo.svg | 9 +- public/images/logos/vox.svg | 14 + public/images/logos/walmart.svg | 35 +- public/images/logos/wattpad.svg | 8 + public/images/logos/waze.svg | 16 + public/images/logos/wikipedia.svg | 132 +- public/images/logos/wolframalpha.svg | 13 +- public/images/logos/xbox.svg | 2 + public/images/logos/yahoo.svg | 40 +- public/images/logos/yandex.svg | 13 +- public/images/logos/yarn.svg | 10 +- public/images/logos/yelp.svg | 16 +- public/images/logos/you.svg | 15 +- public/images/logos/youtube-music.svg | 10 +- public/images/logos/youtube.svg | 17 +- public/images/logos/yts.svg | 366 +++ public/images/logos/zoom.svg | 10 +- public/manifest.json | 38 - public/share.png | Bin 396471 -> 395767 bytes removed_from_manifest | 38 + utils/getLocaleData.ts | 5 + 364 files changed, 9979 insertions(+), 4931 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 app/[locale]/search/[category]/page.tsx create mode 100644 components/BlurBall/BlurBall.module.css rename components/{MovingBlurBackground.tsx => BlurBall/index.tsx} (68%) create mode 100644 components/GradientComponent/GradientComponent.module.css create mode 100644 components/GradientComponent/index.tsx create mode 100644 components/SearchNav/SearchNav.module.css create mode 100644 components/SearchNav/index.tsx create mode 100644 components/SearchOptions/SearchOptions.module.css create mode 100644 components/SearchOptions/index.tsx create mode 100644 components/Welcome/Welcome.module.css create mode 100644 components/Welcome/index.tsx create mode 100644 components/WidgetFeed/WidgetFeed.module.css create mode 100644 components/WidgetFeed/index.tsx create mode 100644 locales/zh-CN.json create mode 100644 pages/api/trends/games.ts delete mode 100644 public/favicon-color.ico create mode 100644 public/findto-sparkle-old.svg create mode 100644 public/fonts/font-medium.woff2 create mode 100644 public/images/logos/apple-vision-pro.svg create mode 100644 public/images/logos/bibliotecas-publicas.svg create mode 100644 public/images/logos/canva.svg delete mode 100644 public/images/logos/carta.svg create mode 100644 public/images/logos/cartacapital.svg create mode 100644 public/images/logos/claro-tv+.svg delete mode 100644 public/images/logos/concursos-brasil.svg create mode 100644 public/images/logos/concursos-no-brasil.svg create mode 100644 public/images/logos/dazn.svg create mode 100644 public/images/logos/douyin.svg create mode 100644 public/images/logos/ea.svg create mode 100644 public/images/logos/empregos.svg create mode 100644 public/images/logos/epic-games.svg create mode 100644 public/images/logos/exame.svg create mode 100644 public/images/logos/expedia.svg delete mode 100644 public/images/logos/foursquare.svg create mode 100644 public/images/logos/galaxy-store.svg create mode 100644 public/images/logos/game-jolt.svg delete mode 100644 public/images/logos/globo.svg create mode 100644 public/images/logos/globocom.svg create mode 100644 public/images/logos/gog.svg create mode 100644 public/images/logos/google-finance.svg create mode 100644 public/images/logos/huawei-appgallery.svg create mode 100644 public/images/logos/iask.svg create mode 100644 public/images/logos/igdb.svg create mode 100644 public/images/logos/ign.svg create mode 100644 public/images/logos/itch.svg create mode 100644 public/images/logos/justica-federal.svg create mode 100644 public/images/logos/justwatch.svg create mode 100644 public/images/logos/kwai.svg create mode 100644 public/images/logos/looke.svg create mode 100644 public/images/logos/meta-quest.svg create mode 100644 public/images/logos/metropoles.svg create mode 100644 public/images/logos/mistral.svg create mode 100644 public/images/logos/mobills.svg create mode 100644 public/images/logos/newsweek.svg create mode 100644 public/images/logos/nubank.svg create mode 100644 public/images/logos/nuuvem.svg create mode 100644 public/images/logos/palco-mp3.svg create mode 100644 public/images/logos/playplus.svg create mode 100644 public/images/logos/playstation.svg create mode 100644 public/images/logos/project-gutenberg.svg create mode 100644 public/images/logos/pubmed.svg create mode 100644 public/images/logos/rawg.svg create mode 100644 public/images/logos/reclame-aqui.svg create mode 100644 public/images/logos/sbt+.svg delete mode 100644 public/images/logos/stf.svg create mode 100644 public/images/logos/sucupira.svg create mode 100644 public/images/logos/temu.svg create mode 100644 public/images/logos/terra.svg create mode 100644 public/images/logos/time.svg create mode 100644 public/images/logos/tribunais-superiores.svg create mode 100644 public/images/logos/ubisoft.svg create mode 100644 public/images/logos/uol-2.svg create mode 100644 public/images/logos/valor.svg create mode 100644 public/images/logos/vox.svg create mode 100644 public/images/logos/wattpad.svg create mode 100644 public/images/logos/waze.svg create mode 100644 public/images/logos/xbox.svg create mode 100644 public/images/logos/yts.svg create mode 100644 removed_from_manifest create mode 100644 utils/getLocaleData.ts diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..2861ae5 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cSpell.words": ["Findto"] +} diff --git a/README.md b/README.md index 7a9a258..3233e62 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,8 @@ Truly free search experience, where the people choices and the planet needs walk | Feature | Description | Status | | ------------------------ | ---------------------------------------------------------------------------------- | ------ | -| **Decentralized search** | Search the same term on diverse Web and AI sources. | ✅ | -| **Realtime trends** | Explore trending stories, topics, contents, products, places, and more nearby you. | ✅ | +| **Search Decentralized** | Search the same term on diverse Web and AI sources. | ✅ | +| **Trending** | Explore trending stories, topics, contents, products, places, and more nearby you. | ✅ | | **Autosuggest** | Get instant suggestions as you type. | ✅ | | **Privacy level** | View the estimate privacy level of selected source. | 🔧 | | **Carbon level** | View the estimate carbon footprint level of selected source. | 🔧 | diff --git a/app/[locale]/about/page.tsx b/app/[locale]/about/page.tsx index c768230..6029198 100644 --- a/app/[locale]/about/page.tsx +++ b/app/[locale]/about/page.tsx @@ -8,7 +8,7 @@ import Button from '@/components/Button' export const metadata = { title: 'About', description: - 'Findto is a decentralized search assistant. Get control over AI and Web search. Explore a healthy internet.', + 'Findto is an assistant for decentralized search on Web, AI and Metaverse.', } export default function PageAbout() { @@ -16,14 +16,11 @@ export default function PageAbout() { return ( -
-
+
+
-

{t('slogan')}

-

- Findto is a decentralized search assistant. Get control over AI and - Web search. Explore a healthy internet. -

+

Decentralized Search for Everyone

+

Findto is an open source assistant for decentralized search.

@@ -31,56 +28,55 @@ export default function PageAbout() {
-
- -
-
-

Take control of algorithms

+

Get control of AI and Web search

- Findto puts people in control of the algorithms. Find anything - switching between diverse sources. More productive and - accessible searches than ever. + Findto puts people in control of algorithms. Switch between + diverse sources, like Web search engines, and generative AI. + Find anything.

-
-
- +
+
+
-

More privacy, less carbon

+

Choice less carbon and more privacy

- Estimated level of privacy and carbon footprint of every - search source. Make better choices - for you and the planet. + Findto is fighthin for a better internet. We are working to + show the estimated carbon footprint and privacy level of every + search source. Better choices are made with transparency.

-
-
- +
+
+
-

Decentralizing AI and Web search

+

Made by people, for people

- The monopoly is dangerous. Findto encourages a truly open - search experience, where people choices matter. We are here - building a better internet. + Findto is an open source project to encourage an accessible + and universal search experience. Where people's choices + matter. Where diversity is key. Search decentralized.

+ +
+ +
-
+
-

Features

-
@@ -88,9 +84,9 @@ export default function PageAbout() {
-

A healthy search experience

-

Decentralized search. Built by people, for people.

-
diff --git a/app/[locale]/community/page.tsx b/app/[locale]/community/page.tsx index defe638..c77fe60 100644 --- a/app/[locale]/community/page.tsx +++ b/app/[locale]/community/page.tsx @@ -4,7 +4,8 @@ import CardsLink from '@/components/CardsLink' import { useTranslations } from 'next-intl' const title = 'Community' -const description = 'Help us build the open source decentralized search.' +const description = + 'Contribute to the Findto project and help us make a better internet!' export const metadata = { title: title, @@ -16,55 +17,71 @@ export default function CommunityPage() { return ( -
+

{t('community') ?? title}

{description}

+ +
- -
-

Welcome to Findto

-

- Findto is an assistant for decentralized search on Web and AI. -

+

Findto App

+

Welcome! Findto is an assistant for decentralized search.

- Our mission is to empower people to engage with the Web and AI in - healthy ways. + Our mission is to empower people to engage with the internet in + healthy ways. On the Web, AI, Metaverse, and more digital spaces.

We're introducing a new search experience, putting control of - search algorithms in your hands. Free and open source. -

- -

- Findto is made by individuals like you. Join us and get involved! + search algorithms in people hands. Findto is 100% open source, + collaborative and free.





-

Researching AI and Web

+

Findto Research

We are researching and are interested in partnerships with - services to strengthen technologies of open access, decentralized - web, responsible AI, privacy, web accessibility, carbon - neutrality, diversity, and digital democracy. Findto is committed - to the United Nations 2030 Agenda for sustainable development. + services, organizations, professionals and volunteers to + strengthen technologies of: +

+
    +
  • Decentralized web
  • +
  • Open access
  • +
  • Responsible AI
  • +
  • Privacy
  • +
  • Web accessibility
  • +
  • + Carbon neutrality and United Nations 2030 Agenda for sustainable + development +
  • +
  • Diversity
  • +
  • Digital democracy
  • +
  • Blockchain
  • +
  • Metaverse
  • +
+ +

+ If you share this vision, feel free to contribute with us. We are + a developing and research community, and we are looking for + partners to join us.

-

If you share this vision, feel free to contribute with us.





+

Code of Conduct

+

- All members of Findto community agree to be kind to each other, - following our{' '} + Findto is made by individuals like you. Join us and get involved! + Note that all members of Findto community agree to be kind to each + other, following our{' '} category?.name.toLowerCase() === 'home', + ) + return ( - - + + - - {/* - - - */} - - ) } diff --git a/app/[locale]/privacy/page.tsx b/app/[locale]/privacy/page.tsx index 8ed9776..b0fe973 100644 --- a/app/[locale]/privacy/page.tsx +++ b/app/[locale]/privacy/page.tsx @@ -9,7 +9,7 @@ export const metadata = { export default function PrivacyPage() { return ( -

+

Privacy Policy

@@ -20,21 +20,22 @@ export default function PrivacyPage() {
-

1. Privacy-First

+

1. Privacy-First Application

- Findto are built on privacy! We respect your privacy regarding any - information we may collect from you across our services at - internet domain http://findto.app{' '} - and communications ("Findto"). + We respect your privacy regarding any information we may collect + from you across our services at internet domain{' '} + http://findto.app and + communications ("Findto").

- Findto don't store any user searches. Because was designed for it. - Findto mission is encourage people choice a healthy internet. - External search provider services may collect and store your - personal data. Thinking about it, Findto displays a "Privacy level - widget" for every search provider, whenever available. + Findto are designed on privacy. Findto don't store any user + searches. Because was designed for it. Findto mission is encourage + people choice a healthy internet. External search provider + services may collect and store your personal data. Thinking about + it, Findto displays a "Privacy level widget" for every search + provider, whenever available.

diff --git a/app/[locale]/search/[category]/page.tsx b/app/[locale]/search/[category]/page.tsx new file mode 100644 index 0000000..b122de1 --- /dev/null +++ b/app/[locale]/search/[category]/page.tsx @@ -0,0 +1,47 @@ +import AppLayout from '@/layouts/AppLayout' +import Search from '@/components/Search' +import WidgetVideoStories from '@/components/WidgetVideoStories' +import WidgetTrends from '@/components/WidgetTrends' +import Banner from '@/components/Banner' +import { Metadata } from 'next/types' +import { getLocaleData } from '@/utils/getLocaleData' +import { ISearchCategory } from '@/interfaces/search' + +export async function generateMetadata({ params }: any): Promise { + const data = await getLocaleData(params.locale) + const selectedCategory = data?.categories?.find( + (category: ISearchCategory) => + category?.name.toLowerCase() === params.category, + ) + + const categoryTitle = + selectedCategory?.name_translated || selectedCategory?.name || 'Findto' + + return { + title: `${categoryTitle}`, + description: `Search decentralized on ${categoryTitle} with the best sources available.`, + } +} + +export default function Page({ params }: any) { + const data = getLocaleData(params.locale) + const selectedCategory = data?.categories?.find( + (category: any) => category?.name.toLowerCase() === params.category, + ) + + return ( + + + + + + + + + {/* <> + + + */} + + ) +} diff --git a/app/[locale]/terms/page.tsx b/app/[locale]/terms/page.tsx index 06c3abb..e8d8058 100644 --- a/app/[locale]/terms/page.tsx +++ b/app/[locale]/terms/page.tsx @@ -9,7 +9,7 @@ export const metadata = { export default function PageTerms() { return ( -

+

Terms of Service

diff --git a/components/Alert/Alert.module.css b/components/Alert/Alert.module.css index f711599..908ee12 100644 --- a/components/Alert/Alert.module.css +++ b/components/Alert/Alert.module.css @@ -1,17 +1,19 @@ .container { - display: grid; + display: inline-grid; grid-template-columns: 22px auto; width: auto; padding: 2.5rem 3rem; - margin: 0 1rem 2.5rem; + margin: 0 2rem; height: auto; color: var(--color-text-black); font-size: var(--font-size); - border-radius: var(--radius-big); + border-radius: 2rem; transition: var(--transition); text-align: left; gap: 2rem; - background: var(--color-white-translucent); + background: var(--color-bg-white); + box-shadow: var(--box-shadow); + max-width: calc(var(--max-size-container) - 4rem); } .container svg { width: 22px; @@ -19,11 +21,13 @@ color: var(--color-text-black); } -@media screen and (max-width: 480px) { +@media screen and (max-width: 576px) { .container { grid-template-columns: 1fr; padding: 2.5rem; gap: 1rem; font-size: var(--font-size-small); + max-width: calc(var(--max-size-container)); + margin: 0 1rem; } } diff --git a/components/Banner/Banner.module.css b/components/Banner/Banner.module.css index d9236bc..f8583fa 100644 --- a/components/Banner/Banner.module.css +++ b/components/Banner/Banner.module.css @@ -1,15 +1,21 @@ .container { + margin: 0 auto; + max-width: var(--max-size-container); +} +.containerBanner { + padding: 4rem; background: var(--color-bg-white); - padding: 3.5rem; - border-radius: var(--radius-big); + border-radius: 3rem; box-shadow: var(--box-shadow); - margin: 1rem 1rem 0; + margin: 2rem; display: grid; grid-template-columns: 1.5fr 1fr; - grid-gap: 8rem; align-items: center; - text-align: left; + grid-template-columns: 1fr; + gap: 0; + text-align: center; } + .container h3 { margin-bottom: 2rem; font-size: var(--font-size-2); @@ -17,66 +23,27 @@ } .container p { margin-bottom: 0.75rem; - font-size: 1.2rem; - color: var(--color-text-black); -} -.container a { - display: flex; - justify-content: center; - align-items: center; - background: var(--color-text-black); - color: var(--color-bg-white); - border: 2px solid transparent; - min-height: var(--size-small); - padding: 0 1rem; - border-radius: var(--radius-big); - width: 100%; - font-size: var(--font-size); - transition: var(--transition); -} -.container a:hover, -.container a:focus { - border-color: var(--color-text-black); + font-size: var(--font-size-big); color: var(--color-text-black); - background: transparent; } -.container a svg { - width: 1.25rem; - height: 1.25rem; - margin-right: 0.5rem; -} -.container div:nth-child(2) { + +.buttonsContainer { display: flex; - flex-direction: column; gap: 1rem; justify-content: center; align-items: center; } -@media screen and (max-width: 600px) { - .container { - padding: 2.5rem; +@media screen and (max-width: 576px) { + .containerBanner { + padding: 2.5rem 2rem; margin: 1rem; } .container h3 { - font-size: 1.5rem; - } -} - -@media screen and (max-width: 940px) { - .container { - overflow: hidden; - grid-template-columns: 1fr; - grid-gap: 0; - text-align: center; + font-size: var(--font-size-3); + margin-bottom: 1.5rem; } .container p { - font-size: var(--font-size); - } - .container a { - font-size: var(--font-size); - } - .container div:nth-child(2) { - margin-top: 1.5rem; + font-size: var(--font-size-small); } } diff --git a/components/Banner/index.tsx b/components/Banner/index.tsx index 88c3f50..5f87e48 100644 --- a/components/Banner/index.tsx +++ b/components/Banner/index.tsx @@ -1,23 +1,37 @@ -import Link from 'next/link' import Styles from './Banner.module.css' -import { IconHeart } from '../SvgIcons' -import { useTranslations } from 'next-intl' +import { useLocale, useTranslations } from 'next-intl' +import { getLocaleData } from '@/utils/getLocaleData' +import SearchNav from '../SearchNav' +import Button from '../Button' +import SvgLogo from '../SvgLogo' export default function Banner() { const t = useTranslations('t') + const locale = useLocale() + const data = getLocaleData(locale) return (
-
-

{t('componentBanner.title')}

-

{t('componentBanner.description')}

-
+
+
+

{t('componentBanner.title')}

+

{t('componentBanner.description')}

+
+ + + +
+ -
- {t('learnMore')} - - {t('donate')} - + {/* */} +
) diff --git a/components/BlurBall/BlurBall.module.css b/components/BlurBall/BlurBall.module.css new file mode 100644 index 0000000..6d56ca1 --- /dev/null +++ b/components/BlurBall/BlurBall.module.css @@ -0,0 +1,21 @@ +.container { + height: 100%; + display: flex; + justify-content: center; + align-items: center; +} + +.icon { + display: inline-block; + width: 8rem; + height: 8rem; + margin-bottom: 2rem; + background-size: 4rem; + background-image: url('/findto-sparkle.svg'); + background-repeat: no-repeat; + background-position: center; + background-color: var(--color-white-translucent-2); + border-radius: 33.333%; + box-shadow: var(--shadow-2); + opacity: 0.5; +} diff --git a/components/MovingBlurBackground.tsx b/components/BlurBall/index.tsx similarity index 68% rename from components/MovingBlurBackground.tsx rename to components/BlurBall/index.tsx index a70dba0..e54b28b 100644 --- a/components/MovingBlurBackground.tsx +++ b/components/BlurBall/index.tsx @@ -1,26 +1,20 @@ -import React from 'react' +'use client' -interface FloatingBallProps { - color: string // Cor hexadecimal -} +import Styles from './BlurBall.module.css' +import GradientComponent from '../GradientComponent' + +const BlurBall = () => { + const color = 'var(--color-text-black)' -const FloatingBall: React.FC = ({ color }) => { const gradient = `linear-gradient(to right, ${color} 0%, ${color} 100%)` const gradientReverse = `linear-gradient(to left, ${color} 0%, ${color} 100%)` - const containerStyle = { - height: '100%', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - } - const ballStyle = { borderRadius: '50%', - height: '8vw', - width: '8vw', + height: '4rem', + width: '4rem', position: 'absolute' as 'absolute', - zIndex: 1, + zIndex: -1, backgroundImage: gradient, animation: 'float 3s ease-in-out infinite', } @@ -47,12 +41,14 @@ const FloatingBall: React.FC = ({ color }) => { } } `} -
+
+ +
) } -export default FloatingBall +export default BlurBall diff --git a/components/Button/Button.module.css b/components/Button/Button.module.css index 569e409..c35b101 100644 --- a/components/Button/Button.module.css +++ b/components/Button/Button.module.css @@ -1,10 +1,10 @@ .button { display: inline-flex; + gap: 0.75rem; margin: 0.5rem 0 0; width: auto; - padding: 0 2.8rem; + padding: 0 2.4rem; height: var(--size-big); - color: var(--color-black); font-size: var(--font-size-big); border: none; border-radius: var(--radius-full); @@ -16,3 +16,22 @@ transform: translateY(-1px); box-shadow: var(--box-shadow); } + +.button svg { + width: 1.25rem; + height: 1.25rem; +} + +.black { + background: var(--color-text-black); + color: var(--color-bg-white); +} + +@media screen and (max-width: 576px) { + .button { + gap: 0.5rem; + padding: 0 2rem; + height: var(--size-small); + font-size: var(--font-size); + } +} diff --git a/components/Button/index.tsx b/components/Button/index.tsx index 1e1bd4d..c2f72dc 100644 --- a/components/Button/index.tsx +++ b/components/Button/index.tsx @@ -2,15 +2,36 @@ import Styles from './Button.module.css' import Link from 'next/link' type Props = { - url?: string - color?: string - children: string + url: string + color: 'colors' | 'black' | 'white' + size?: 'big' | 'small' + external?: boolean + children: string | JSX.Element } export default function Button(props: Props) { + const { url, color, size, external, children } = props + + // Concatena classes manualmente + const className = `${Styles.button} ${Styles[color]} ${ + size ? Styles[size] : '' + }`.trim() + + if (external) { + return ( + + {children} + + ) + } + return ( - - {props.children} + + {children} ) } diff --git a/components/ButtonGeolocation/ButtonGeolocation.module.css b/components/ButtonGeolocation/ButtonGeolocation.module.css index 31bc2a3..dc84119 100644 --- a/components/ButtonGeolocation/ButtonGeolocation.module.css +++ b/components/ButtonGeolocation/ButtonGeolocation.module.css @@ -6,8 +6,8 @@ .button { position: relative; padding: 0 2rem; - color: var(--color-white); - background: var(--color-black); + color: var(--color-bg-white); + background: var(--color-text-black); border: none; border-radius: var(--radius-full); cursor: pointer; @@ -16,19 +16,10 @@ display: flex; gap: 0.5rem; align-items: center; -} -.button:hover, -.button:focus { - background: var(--color-white); - color: var(--color-black); box-shadow: var(--box-shadow); } -.button:hover svg, -.button:focus svg { - color: var(--color-black); -} .button svg { - color: var(--color-white); + color: var(--color-bg-white); width: 20px; height: 20px; } diff --git a/components/CardsFeat/CardsFeat.module.css b/components/CardsFeat/CardsFeat.module.css index 0fd80db..37961b3 100644 --- a/components/CardsFeat/CardsFeat.module.css +++ b/components/CardsFeat/CardsFeat.module.css @@ -1,3 +1,10 @@ +.container { + transition: var(--transition-hover); +} +.container h2 { + color: var(--color-black) !important; +} + .card { display: flex; flex-wrap: wrap; @@ -5,40 +12,50 @@ grid-gap: 3rem; padding: 3rem 0; } -.card div { +.card li { display: flex; - width: 280px; + width: 12rem; flex-direction: column; align-items: center; text-align: center; } -.card figure { +.card li figure { display: flex; - background: var(--color-white-translucent-2); - height: 4.5rem; - width: 4.5rem; - margin: 0 auto; - border-radius: var(--radius-full); + background-color: var(--color-white-translucent); + border-radius: 33.333%; box-shadow: var(--shadow-2); + height: 5rem; + width: 5rem; + margin: 0 auto; align-items: center; justify-content: center; } -.card h3 { - margin-top: 2rem; +.card li h3 { + margin-top: 1.5rem; + /* font-weight: 400; */ + font-size: 1.05rem; } -.card p { - font-size: var(--font-size-small); +.card li p { + font-size: var(--font-size); } -.card svg { +.card li svg { width: 1.5rem; height: 1.5rem; } -@media screen and (min-width: 940px) { - .card { - grid-gap: 5rem; +@media screen and (max-width: 576px) { + .card li { + width: 8rem; + } + .card li figure { + height: 4rem; + width: 4rem; + } + .card li svg { + width: 1.25rem; + height: 1.25rem; } - .card figure { - margin: 0; + .card li p { + font-size: var(--font-size-small); } } diff --git a/components/CardsFeat/index.tsx b/components/CardsFeat/index.tsx index ac44f03..9762117 100644 --- a/components/CardsFeat/index.tsx +++ b/components/CardsFeat/index.tsx @@ -1,11 +1,14 @@ import Style from './CardsFeat.module.css' + import { IconAccessibility, IconLanguage, IconLeaf, IconMic, + IconOpenSource, IconSearch, IconShield, + IconStories, IconText, IconTrending, IconVisualSearch, @@ -16,77 +19,83 @@ interface Feature { icon: JSX.Element title: string description: string - note?: string } // Create an array of feature items with their types const features: Feature[] = [ { icon: , - title: 'Decentralized search', - description: 'Quickly search the same term on diverse AI and Web sources.', + title: 'Decentralized Search', + description: 'Search on diverse sources at once.', }, { icon: , - title: 'Realtime trends', - description: - 'Explore trending topics, contents, places, events, and more nearby you.', + title: 'Trends', + description: 'Real-time trends nearby you.', + }, + { + icon: , + title: 'Stories', + description: 'Discover newest stories.', }, { icon: , - title: 'Autosuggest', - description: - 'Automatic suggestions of terms as you type, to make fast searches.', + title: 'Autocomplete', + description: 'Automatic suggestions of terms as you type.', + }, + { + icon: , + title: 'Voice Search', + description: 'Search anywhere using your voice.', + }, + { + icon: , + title: 'Visual Search *', + description: 'Search on supported sources with an image.', }, { icon: , - title: 'Privacy level', + title: 'Privacy Level *', description: 'Estimated privacy level of search source.', - note: '* In development', }, { icon: , - title: 'Carbon level', - description: 'Estimated carbon footprint level of search source.', - note: '* In development', + title: 'Carbon Footprint *', + description: 'Estimated carbon footprint of search source.', }, { - icon: , - title: 'Voice search', - description: 'Use your voice to search anywhere.', + icon: , + title: 'Internationalization', + description: 'Choose your country for local sources, or international.', }, { icon: , title: 'Accessibility', description: - 'Balanced contrast, dark theme, keyboard navigation and screen readers support.', + 'Balanced contrast, screen reader support, keyboard navigation and dark theme.', }, { - icon: , - title: 'Internationalization', - description: - 'Choose your country for local sources, or opt for an international search.', - }, - { - icon: , - title: 'Visual search', - description: - 'Use an image or your camera to search across supported sources.', - note: '* In development', + icon: , + title: 'Open Source', + description: ' Findto is an open source project.', }, ] export default function CardsFeat() { return ( -
- {features.map((feature, index) => ( -
-
{feature.icon}
-

{feature.title}

-

{feature.description}

- {feature.note &&

{feature.note}

} -
- ))} +
+

Features

+ +
    + {features.map((feature, index) => ( +
  • +
    {feature.icon}
    +

    {feature.title}

    +

    {feature.description}

    +
  • + ))} +
+

* Some features are in development.

) } diff --git a/components/CardsLink/CardsLink.module.css b/components/CardsLink/CardsLink.module.css index 689cdee..f02a0b0 100644 --- a/components/CardsLink/CardsLink.module.css +++ b/components/CardsLink/CardsLink.module.css @@ -4,17 +4,16 @@ grid-gap: 1.5rem; flex-wrap: wrap; justify-content: center; - margin: 0 0 8rem; + margin-top: 5rem; } .cards a { position: relative; margin: 0; padding: 1rem; - max-width: 15.5rem; + max-width: 10rem; width: 100%; color: inherit; text-decoration: none; - border-radius: var(--radius); color: var(--color-black); top: 0; transition: ease 0.25s; @@ -22,6 +21,9 @@ display: flex; align-items: center; justify-content: center; + background-color: var(--color-white-translucent); + border-radius: var(--radius); + box-shadow: var(--shadow-2); } .cards a:hover, .cards a:focus { @@ -52,3 +54,16 @@ width: 2rem; height: 2rem; } + +@media screen and (max-width: 576px) { + .cards { + grid-gap: 1rem; + } + .cards a { + max-width: 8rem; + } + .cards svg { + width: 1.5rem; + height: 1.5rem; + } +} diff --git a/components/CardsLink/index.tsx b/components/CardsLink/index.tsx index 7636f5c..dec5259 100644 --- a/components/CardsLink/index.tsx +++ b/components/CardsLink/index.tsx @@ -6,6 +6,7 @@ import { IconX, IconGitHub, IconDiscord, + IconInstagram, } from '../SvgIcons' import { useTranslations } from 'next-intl' @@ -23,10 +24,16 @@ export default function CardsLink() { const cards: ICardsLink[] = [ { title: t('donate'), - url: 'https://ko-fi.com/findto', + url: 'https://patreon.com/findto', icon: , active: true, }, + { + title: t('feedback.title'), + url: t('feedback.url'), + icon: , + active: true, + }, { title: 'GitHub', url: 'https://github.com/lucasm/findto', @@ -45,12 +52,6 @@ export default function CardsLink() { icon: , active: false, }, - { - title: t('feedback.title'), - url: t('feedback.url'), - icon: , - active: true, - }, { title: 'Get Pro version', url: '/pricing', @@ -59,9 +60,9 @@ export default function CardsLink() { internal: true, }, { - title: 'Follow on Instagram', + title: 'Instagram', url: 'https://instagram.com/findtoapp', - icon: <>, + icon: , active: false, }, { @@ -80,8 +81,7 @@ export default function CardsLink() { + target={item.internal ? '_self' : '_blank'}>
{item.icon}

{item.title}

diff --git a/components/CookiesPopup/CookiesPopup.module.css b/components/CookiesPopup/CookiesPopup.module.css index bf417dc..62e07ee 100644 --- a/components/CookiesPopup/CookiesPopup.module.css +++ b/components/CookiesPopup/CookiesPopup.module.css @@ -1,19 +1,21 @@ .cookiesPopup { position: fixed; - bottom: -8rem; + bottom: 0; right: 1rem; - left: 1rem; + left: unset; display: flex; + width: 100%; + max-width: 20rem; gap: 1rem; - background: var(--color-black); + background: var(--color-text-black); border-radius: 24px; - color: var(--color-white); padding: 2rem; text-align: center; transition: transform 0.5s ease-in-out; z-index: 1000; align-items: center; flex-direction: column; + box-shadow: var(--box-shadow); } .cookiesPopup div { display: flex; @@ -21,37 +23,28 @@ align-items: center; } .cookiesPopup p { + color: var(--color-bg-white); font-size: var(--font-size-small); } .slideUp { - transform: translateY(-100%); + transform: translateY(-1rem); } .slideDown { transform: translateY(100%); } .cookiesPopup button { - background: var(--color-white); - color: var(--color-black); + background: var(--color-bg-white); + color: var(--color-text-black); + border: none; padding: 10px 20px; border-radius: var(--radius-small); cursor: pointer; - font-size: var(--font-size); + font-size: var(--font-size-small); } .cookiesPopup a { font-size: var(--font-size-small); } - -@media screen and (min-width: 900px) { - .cookiesPopup { - bottom: -7.75rem; - right: 1rem; - left: unset; - } - .cookiesPopup p { - font-size: var(--font-size-5); - } -} diff --git a/components/CookiesPopup/index.tsx b/components/CookiesPopup/index.tsx index 087d620..30c4384 100644 --- a/components/CookiesPopup/index.tsx +++ b/components/CookiesPopup/index.tsx @@ -19,7 +19,7 @@ const CookiesPopup = () => { }) useEffect(() => { - if (!isAccepted && locale !== 'pt-BR') { + if (!isAccepted) { setIsVisible(true) } }, [isAccepted]) @@ -37,10 +37,13 @@ const CookiesPopup = () => { className={`${styles.cookiesPopup} ${ isVisible ? styles.slideUp : styles.slideDown }`}> -

Findto uses Cookies for better navigation

-
+

+ {t('componentCookiesPopup.title')}{' '} {t('privacy')} - + {'.'} +

+
+
) diff --git a/components/Footer/Footer.module.css b/components/Footer/Footer.module.css index 5ddffcb..d1ea4a1 100644 --- a/components/Footer/Footer.module.css +++ b/components/Footer/Footer.module.css @@ -1,16 +1,23 @@ +.footer { + margin: 0 auto; + width: 100%; + max-width: var(--max-size-container); +} + .container { - text-align: center; - padding: 3rem 2rem; + position: relative; display: flex; - gap: 2rem; + gap: 1.5rem; align-items: center; - justify-content: flex-start; + justify-content: center; flex-direction: column; + margin: 0 2rem; + padding: 1rem 0 2rem; } .container ul { display: flex; - gap: 1.5rem; + gap: 1.25rem; align-items: center; justify-content: center; flex-wrap: wrap; @@ -18,6 +25,9 @@ } .container ul li { font-size: 0; + display: flex; + gap: 1rem; + text-align: left; } .container ul li:last-child { display: flex; @@ -29,6 +39,7 @@ font-size: var(--font-size-small); color: var(--color-black-translucent-50); font-weight: 400; + text-align: center; } .container ul li a:has(svg) { @@ -36,8 +47,8 @@ } .container ul li a svg { - width: 1rem; - height: 1rem; + width: 0.8rem; + height: 0.8rem; fill: var(--color-black-translucent-50); transition: var(--transition); } @@ -46,6 +57,18 @@ fill: var(--color-text-black); } +.container figure svg { + width: 4rem; + height: 4rem; + fill: var(--color-black-translucent-50); + transition: var(--transition); + opacity: 1; +} +.container figure:hover svg, +.container figure:focus svg { + fill: var(--color-text-black); +} + .container p a, .container a { transition: var(--transition); @@ -56,10 +79,7 @@ color: var(--color-text-black); } -@media screen and (max-width: 600px) { - .container { - padding: 2rem; - } +@media screen and (max-width: 1024px) { .container ul { gap: 1rem; } diff --git a/components/Footer/index.tsx b/components/Footer/index.tsx index 678714a..ca3fd0f 100644 --- a/components/Footer/index.tsx +++ b/components/Footer/index.tsx @@ -1,9 +1,14 @@ -'use client' - import Style from './Footer.module.css' import Link from 'next/link' import SvgLogo from '../SvgLogo' -import { IconGitHub, IconX, IconInstagram, IconBluesky } from '../SvgIcons' +import { + IconGitHub, + IconX, + IconInstagram, + IconBluesky, + IconDiscord, + IconLinkedIn, +} from '../SvgIcons' import { useTranslations } from 'next-intl' export default function AppFooter() { @@ -15,27 +20,32 @@ export default function AppFooter() {
  • -
    - - - -
    + + +
  • - Findto © {year}{' '} - {/* Lucas Menezes */} + Findto © {year} {t('slogan')} + {'. '} {t('copyright')} + + {' '} + Lucas Menezes + + {'. '}

  • +
+
  • {t('about')}
  • {t('community')}
  • - {/*
  • - +
  • + {t('donate')}
  • @@ -43,13 +53,16 @@ export default function AppFooter() { {t('feedback.title')} - */} +
  • {t('terms')}
  • {t('privacy')}
  • +
+ +
  • +
  • + + + +
  • +
  • + + + +
- {/* - - - - - - - */} - - {/* - LinkedIn - - */} - {/* + {/*
*/} + + {/*
*/} + + {/*
+
+

+ Bem-vindo ao Fundo Animado e Colorido +

+
+
*/} + + ) +} diff --git a/components/Header/Header.module.css b/components/Header/Header.module.css index 2a143e3..b2b7f19 100644 --- a/components/Header/Header.module.css +++ b/components/Header/Header.module.css @@ -1,185 +1,221 @@ .header { - position: relative; + position: absolute; display: flex; align-items: center; vertical-align: middle; justify-content: space-between; width: 100%; - flex-direction: column; + max-width: var(--max-size-container); + background: transparent; + margin: 0 auto; + right: 0; + left: 0; } + .header svg { width: 20px; height: 20px; - color: var(--color-text-black); } + .header button { background: transparent; border: none; - opacity: var(--opacity); + height: 4rem; + padding: 0 1rem; + gap: 0.5rem; + background: transparent; + font-size: var(--font-size); + font-weight: 400; + display: flex; + align-items: center; + color: var(--color-black); } .header button:hover, .header button:focus, .header a:hover, .header a:focus { opacity: 1; - background: var(--color-black-translucent); } -.logo { +.header button figure { display: flex; - gap: 0.5rem; - align-items: center; - padding: 0 1rem; - margin: 0.75rem; - height: var(--size-big); - border-radius: var(--radius-full); - color: var(--color-text-black); + padding: 0.5rem; + border-radius: 0.5rem; +} +.header button:hover figure, +.header button:focus figure { + background: var(--color-black-translucent); } -.nav { - width: 100%; - height: 100%; - overflow-y: auto; - overflow-x: hidden; - display: flex; - justify-content: center; - align-items: center; +.openMenu button { + z-index: 4; +} +.openMenu figure { + background: var(--color-bg-white) !important; + box-shadow: var(--box-shadow); +} +.openMenu figure svg { + fill: var(--color-text-black); } -.nav ul { - white-space: nowrap; - overflow-x: auto; - overflow-y: hidden; +.buttonsContainer { display: flex; - padding: 0.24rem 0; } -.nav li { - display: inline-block; +.buttonsContainer button:last-child:before { + content: ''; + position: relative; + height: 2rem; + width: 1px; + margin-right: 1rem; + background: #000; + opacity: var(--opacity); } -.nav button { +.buttonSettings { + font-size: 0 !important; + gap: 0 !important; +} + +.logoContainer { display: flex; align-items: center; - justify-content: center; - height: 5rem; - border-radius: var(--radius); - font-size: var(--font-size-small); - color: var(--color-text-black); - padding: 0 1rem; - gap: 0.35rem; - min-width: 4rem; - flex-direction: column; +} +.logo { + display: flex; + align-items: center; + gap: 0.75rem; + line-height: 3.5rem; + padding: 2rem; + height: var(--size-big); + color: var(--color-black); } .containerSettings { - display: grid; - grid-gap: 0.5rem; - margin-top: 1rem; + padding: 2rem; + display: flex; + gap: 2rem; + flex-direction: column; +} +.containerSettings h3 { + font-size: var(--font-size); + font-weight: 400; + margin: 0 0 1rem 0; } -.containerSettings:not(:last-of-type) { - margin-bottom: 2rem; +.containerSettings div div { + display: flex; + gap: 0.5rem; + flex-direction: column; } + .containerSettings button, .containerSettings a { - border-radius: var(--radius); + width: 100%; display: flex; + align-items: center; + justify-content: flex-start; height: var(--size-small); - font-size: var(--font-size-small); + font-size: var(--font-size); + font-weight: 400; background: var(--color-black-translucent); color: var(--color-text-black); - align-items: center; - opacity: 1; + border-radius: var(--radius); + padding: 0; + gap: 0; } .containerSettings button svg, .containerSettings a svg { margin: 0 1rem; } .containerSettings select { - font-size: var(--font-size-small) !important; -} -.header .iconSettings { - position: absolute; - right: 0; - top: 0; - padding: 0.75rem; -} - -.header .iconSettings button { - width: var(--size-big); - height: var(--size-big); - font-size: 0; - justify-content: center; - border-radius: var(--radius-full); -} -.containerSettings h3 { - font-size: 1.25rem; - margin: 0 0 0.5rem 0; + width: 100%; } -.submenu ul { - align-items: flex-start; - background: var(--color-bg-white); +.layer { position: fixed; + /* background: rgb(0 0 0 / 50%); */ top: 0; - right: 0; + left: 0; width: 100%; - max-width: 320px; height: 100%; - bottom: var(--size-big); - flex-direction: column; - border-radius: 0; - box-shadow: var(--box-shadow); - padding: 1.25rem 0; + z-index: 2; + backface-visibility: hidden; + visibility: hidden; + opacity: 0; + transition: all 0.25s cubic-bezier(0, 0, 0.3, 1); +} +.layerActive { + visibility: visible; + opacity: 1; + animation: fade 0.25s ease; +} +.removeScroll { overflow: hidden; - z-index: 99999; } -.submenu ul li { - width: 100%; + +@keyframes fade { + from { + opacity: 0; + visibility: hidden; + } + to { + opacity: 1; + visibility: visible; + } } -.submenu ul li button { - border-radius: 0; + +.nav { + position: absolute; + height: auto; width: 100%; - padding: 0 2rem; - height: 3rem; - justify-content: flex-start; - flex-direction: row; + max-width: 22rem; + background: var(--color-bg-white); + right: 1rem; + top: 4rem; + transition: all var(--navDrawerDurationEnterMS) var(--easingDecelerate); + transform: translateX(50%); + visibility: hidden; + opacity: 0; + z-index: 3; + overflow: auto; + margin: 0 auto; + border-radius: 2rem; + box-shadow: var(--box-shadow); + user-select: none; +} +.openNav { + visibility: visible; + opacity: 1; + transform: translateX(0); } -@media screen and (max-width: 940px) { - .nav ul { - padding-right: 1rem; - padding-left: 1rem; - } - .nav button { - width: var(--size-large); - height: var(--size-large); - font-size: 0; - gap: 0; - padding: 0; - } - .nav button { - height: var(--size-small); - min-width: var(--size-small); - } +.nav p { + font-size: var(--font-size-small); + font-weight: 400; +} - .logo svg { - width: 18px; - height: 18px; +@media screen and (max-width: 576px) { + .logo { + height: 3rem; + padding: 0 0.75rem; } - .logo, - .header .iconSettings button { - height: 2.5rem; - margin: 0.5rem; - } - .header .iconSettings button { - width: 2.5rem; + + .nav { + top: 3rem; + right: 0.5rem; } - .header .iconSettings { - padding: 0; + + .header { + padding: 0 0.5rem; } - .containerSettings button, - .containerSettings a { - font-size: var(--font-size-small); + .header .buttonsContainer button { + font-size: 0; + gap: 0; + height: 3rem; + padding: 0 0.5rem; } + + /* .buttonsContainer button:nth-child(2) { + display: none; + } */ } diff --git a/components/Header/index.tsx b/components/Header/index.tsx index 04aa08e..0d9f6bb 100644 --- a/components/Header/index.tsx +++ b/components/Header/index.tsx @@ -2,74 +2,32 @@ import Style from './Header.module.css' import Link from 'next/link' -import { useEffect, useRef, useState } from 'react' -import { useRouter, useSearchParams } from 'next/navigation' +import { useState } from 'react' +import { useTheme } from 'next-themes' import { useTranslations } from 'next-intl' -import { useSearch } from '@/contexts/SearchContext' -import Modal from '@/components/Modal' -import SvgLogo from '@/components/SvgLogo' +import SelectLanguage from '@/components/SelectLanguage' +import SearchNav from '@/components/SearchNav' import { - IconSettings, - IconGlobe, - IconImage, - IconVideo, - IconMusic, - IconPeople, - IconSparkle, - IconLocation, - IconCart, - IconCode, - IconBook, - IconBriefcase, - IconNews, - IconBank, + IconUser, IconFeedback, IconHeart, IconMoon, IconSun, - IconFinance, - IconApps, - IconDownload, - Icon, - IconMore, - IconGames, IconThemeSystem, + IconMenu, } from '@/components/SvgIcons' -import { normalizeId } from '@/utils/formats' -import { ISearchCategory } from '@/interfaces/search' -import SelectLanguage from '@/components/SelectLanguage' -import { useTheme } from 'next-themes' +import { getLocaleData } from '@/utils/getLocaleData' +import SvgLogo from '../SvgLogo' -export default function AppHeader() { - const t = useTranslations('t') - const { theme, setTheme } = useTheme() - const router = useRouter() - const searchParams = useSearchParams() - const view = searchParams?.get('view') - const { - data, - category, - setCategory, - refSearchTabs, - refSearchInput, - isMobileViewport, - } = useSearch() +interface Props { + locale: string +} - const [showModal, setShowModal] = useState(false) - const [isSubmenuOpen, setIsSubmenuOpen] = useState(false) - const [menuItens, setMenuItens] = useState(null) - const [submenuItems, setSubmenuItems] = useState(null) - const submenuRef = useRef(null) - const [maxItemsInHeader, setMaxItemsInHeader] = useState(data?.length) - const [pageHeight, setPageHeight] = useState(0) +const AppHeader = ({ locale }: Props) => { + const t = useTranslations('t') + const data = getLocaleData(locale) - const handleSubmenu = () => { - setIsSubmenuOpen(!isSubmenuOpen) - } - const handleModal = () => { - setShowModal(!showModal) - !isMobileViewport && refSearchInput.current.focus() - } + const { theme, setTheme } = useTheme() const handleTheme = () => { if (theme === 'light') { setTheme('dark') @@ -84,233 +42,140 @@ export default function AppHeader() { // Assumindo que se não for 'light' ou 'dark', é 'system' setTheme('light') } - const handleCategory = (category: string) => { - try { - refSearchTabs?.current?.['tab_' + category]?.click() - setCategory(category) - window.localStorage.setItem('category', category) - router.push(`?view=${category}`) - } catch (error) { - console.error('Error loading category ' + category, error) - refSearchTabs?.current?.['tab_Web']?.click() - } - } - const handleCategoryIcon = (category: string) => { - switch (category) { - case 'Web': - return - case 'AI': - return - case 'Image': - return - case 'Videos': - return - case 'Music': - return - case 'Social': - return - case 'Local': - return - case 'Academic': - return - case 'Shopping': - return - case 'News': - return - case 'Job': - return - case 'Code': - return - case 'Legal': - return - case 'Apps': - return - case 'Finance': - return - case 'Games': - return - case 'Torrent': - return - default: - return - } - } - const renderMenuItem = (name: string, nameTranslated: any) => { - return ( - - ) - } - - // largura da página - useEffect(() => { - // largura inicial da página - setPageHeight(window.innerWidth) - - const handleResize = () => { - // atualiza a largura da página quando a janela é redimensionada - setPageHeight(window.innerWidth) - } - - // evento de redimensionamento da janela - window.addEventListener('resize', handleResize) - - // remove o ouvinte de evento quando o componente é desmontado - return () => window.removeEventListener('resize', handleResize) - }, []) - - // header: limit of items - useEffect(() => { - if (!isMobileViewport && pageHeight > 0) { - if (pageHeight < 1100) { - setMaxItemsInHeader(11) - } else if (pageHeight < 1200) { - setMaxItemsInHeader(12) - } else { - setMaxItemsInHeader(13) - } - } - // se houver mais itens no menu do que o limite move para o submenu - if (!isMobileViewport && data?.length > maxItemsInHeader) { - const remainingItems = data?.slice(maxItemsInHeader) - setMenuItens(data?.slice(0, maxItemsInHeader)) - setSubmenuItems(remainingItems) - } else { - setMenuItens(data) - setSubmenuItems([]) - } - }, [data, isMobileViewport, pageHeight, maxItemsInHeader]) + const [showSettings, setShowSettings] = useState(false) + const handleSettings = () => { + setShowSettings(!showSettings) + } - // state: change category by URL param - useEffect(() => { - if (view) { - if (!!data?.find((item: any) => item.name === view)) { - handleCategory(view) - } - } - }, [data, view]) + const [showMenu, setShowMenu] = useState(false) + const handleMenu = () => { + setShowMenu(!showMenu) + } - useEffect(() => { - function handleClickOutside(event: MouseEvent) { - if (submenuRef.current) { - if (!submenuRef.current.contains(event.target as Node)) { - setIsSubmenuOpen(false) - } - } - } - - document.addEventListener('mousedown', handleClickOutside) - return () => { - document.removeEventListener('mousedown', handleClickOutside) - } - }, []) + const showLayer = showMenu || showSettings return (
- refSearchInput.current.focus()}> - - Findto - +
+ + + Findto + +
-
- */} + + + +
- + {showMenu && ( + + )} - {showModal && ( - + {showSettings && ( + + )} -
- + {showLayer && ( +
{ + setShowMenu(false) + setShowSettings(false) + }}>
)}
) } + +export default AppHeader diff --git a/components/Search/Search.module.css b/components/Search/Search.module.css index c6e6d93..56a29a7 100644 --- a/components/Search/Search.module.css +++ b/components/Search/Search.module.css @@ -1,106 +1,86 @@ -/* Tabs */ -.tabs { - width: 100%; -} -.tabs ul { - display: none; - flex-wrap: wrap; - width: 100%; - justify-content: center; -} -.tabs button { - padding: 0 1rem; - border: 0; - font-size: var(--font-size-small); - color: var(--color-text-black); - height: var(--size-small); - border-radius: var(--radius-full); - opacity: var(--opacity); - background: transparent; - line-height: 1; -} -.tabs button:hover, -.tabs button:focus { - background: var(--color-black-translucent); - opacity: 1; -} - /* Search */ -.searchContainer { - background: transparent; - border-radius: var(--radius-big); - margin: 0 0 8rem; -} -.searchContainer label { - font-size: 0; -} -.searchContainer select { - background-color: var(--color-white-translucent); - height: var(--size-small); - box-shadow: var(--box-shadow); - border-radius: var(--radius-full); - padding: 0 3rem 0 1.5rem; - color: var(--color-black); +.container { + margin: 0 auto 6rem; + background: var(--background-linear-gradient); + transition: var(--transition-hover); } .searchContainer2 { - padding: 3rem; display: flex; + margin: 0 auto; + padding: 6rem 2rem 4rem; + gap: 2rem; + flex-direction: column; flex-wrap: wrap; justify-content: center; align-items: center; - flex-direction: column; - gap: 1.75rem; - transition: var(--transition-hover); - border-radius: var(--radius-big); - - background: transparent; - color: var(--color-text-black); + max-width: var(--max-size-container); } + +/* Input */ .searchInputContainer { max-width: 750px; width: 100%; + /* padding: 0 1rem; */ } -/* Input */ .searchInput { - position: relative; display: flex; align-items: center; + background: var(--color-white); + padding: 0.375rem 1.25rem; + gap: 0; + border-radius: 2rem; +} +.searchInput label { + font-size: 0; } + +/* .searchInput:focus .searchInputContainer, +.searchInput:active .searchInputContainer { + box-shadow: var(--box-shadow); +} */ + +.textareaContainer { + position: relative; + width: 100%; +} + .searchInput textarea { resize: none; position: relative; display: flex; float: none; height: auto; - min-height: 3rem; width: 100%; margin: 0; - padding: 1rem 8.5rem 1rem 1.6rem; + min-height: 3rem; + padding: 0.75rem 5.5rem 0.75rem 1.25rem; border: none; outline: none; color: var(--color-black); - font-weight: bold; - font-size: var(--font-size); + font-weight: 400; + font-size: var(--font-size-big); letter-spacing: normal; text-align: left; - background: var(--color-white); - box-shadow: var(--box-shadow); - border-radius: 1.75rem; + background: transparent; + border: none; + box-shadow: none; transition: all ease-in-out 0.25s; } -.searchInput textarea:hover, -.searchInput textarea:focus { - box-shadow: var(--shadow-hover); -} .searchActions { position: absolute; - right: 0.8rem; + top: 0; + bottom: 0; + right: 0.5rem; display: flex; align-items: center; } +.searchButton { + width: 2.5rem; +} + .searchButton, .resetButton { font-size: 0; @@ -108,122 +88,117 @@ align-items: center; justify-content: center; height: 2rem; - width: 2rem; background: var(--color-black); border-radius: var(--radius-full); border: 0; } -.searchButton { - margin-left: 0.5rem; -} .searchButton svg { color: var(--color-white); rotate: 90deg; } .searchButton svg, .resetButton svg { - width: 18px; - height: 18px; + width: 20px; + height: 20px; } .resetButton { display: none; - width: var(--size-small); - opacity: 0.5; + align-items: center; + justify-content: center; border-radius: 0; background: transparent; color: var(--color-black); - height: var(--size-small); - width: 2rem; + width: 1.5rem; + height: 3rem; + opacity: var(--opacity); } .resetButton:focus, .resetButton:hover { opacity: 1; } -/* Placeholder */ -.searchPlaceholder { - position: absolute; +.searchLogo { display: flex; - gap: 0.8rem; - justify-content: flex-start; align-items: center; - width: auto; - height: 32px; - margin: 1rem 0 1rem 2rem; - text-align: left; - font-size: var(--font-size-small); - font-weight: bold; - color: var(--color-black); - z-index: 1; - opacity: 0.45; - cursor: text; + height: 1.5rem; + width: 1.5rem; + background-repeat: no-repeat; + background-position: center; + background-size: 1.5rem 1.5rem; + opacity: var(--opacity); } -.searchPlaceholder figcaption { + +/* Buttons */ +.buttons { + width: 100%; +} +.buttons ul { + display: flex; + flex-wrap: wrap; + justify-content: center; + width: 100%; +} +.buttons button { + padding: 0 1rem; + border: 0; + font-size: var(--font-size); + font-weight: 400; color: var(--color-black); + height: var(--size-small); + border-radius: var(--radius-full); + background: transparent; } -.searchPlaceholder figure { - width: 8rem; - height: 1.8rem; - background-repeat: no-repeat; - background-position: 0; - /* background-color: yellow; */ +.buttons button:hover, +.buttons button:focus { + background: var(--color-black-translucent); + opacity: 1; } - -.widgetContainer { - display: grid; - align-items: start; - grid-template-columns: 1fr 260px; - grid-gap: 2rem; - margin: 2rem auto 0; +.buttonActive { + background: var(--color-bg-white) !important; + opacity: 1 !important; + color: var(--color-text-black) !important; + /* box-shadow: var(--box-shadow); */ } -@media screen and (max-width: 940px) { - .nav, - .tabs { - width: 100%; - } - .nav ul, - .tabs ul { - padding: 0 1rem; +@media screen and (max-width: 576px) { + .buttons ul { + padding: 0 1rem 1rem; white-space: nowrap; overflow-x: auto; overflow-y: hidden; text-align: center; + display: inline-block; } - .nav li, - .tabs li { + .buttons li { width: auto; display: inline-block; } - - .tabs button { + .buttons button { margin: 0.25rem 0; font-size: 0.8rem; height: 1.5rem; padding: 0 0.75rem; } - .searchInputContainer, - .widgetContainer { - padding-left: 1rem; - padding-right: 1rem; + .searchLogo { + height: 1.25rem; + width: 1.25rem; + background-size: 1.25rem 1.25rem; } - .widgetContainer { - grid-template-columns: 1fr; + .searchInput { + padding: 0.3rem 0.85rem; + border-radius: 1.5rem; } - .searchInput textarea { font-size: var(--font-size); - min-height: 3rem; - padding: 0.85rem 6.5rem 0.75rem 1.25rem; - border-radius: 1.5rem; + min-height: 2.375rem; + padding: 0.5rem 3.5rem 0.5rem 0.75rem; } - .searchButton, - .resetButton { - height: 2rem; - width: 2rem; + .searchButton { + height: 1.6rem; + width: 2.2rem; } .searchButton:hover svg, .searchButton:focus svg { @@ -233,33 +208,26 @@ width: 18px; height: 18px; } + .resetButton svg { - width: 14px; - height: 14px; - } - .resetButton { - width: 1.75rem; + width: 18px; + height: 18px; } .searchActions { - right: 0.5rem; + right: 0.25rem; } - .searchPlaceholder { - margin: 1rem 1.5rem; - } - .searchPlaceholder figure { - height: 26px; - } - - .searchContainer { - margin: 0 0 3rem; - border-radius: 0; + .container { + margin: 0 auto 3rem; + padding: 5rem 0 0 0; } .searchContainer2 { - padding: 2rem 0 2.5rem; + padding: 0 0 2rem; gap: 1rem; - border-radius: 0; - box-shadow: none; + } + + .searchInputContainer { + padding: 0 1rem; } } diff --git a/components/Search/index.tsx b/components/Search/index.tsx index 392b22f..d009aea 100644 --- a/components/Search/index.tsx +++ b/components/Search/index.tsx @@ -1,37 +1,48 @@ 'use client' import { useRef, useState, useEffect } from 'react' +import { useLocale, useTranslations } from 'next-intl' +import { useSearchParams } from 'next/navigation' import Style from './Search.module.css' import { normalizeId } from '@/utils/formats' import { useSearch } from '@/contexts/SearchContext' -import SearchTitle from '@/components/SearchTitle' import { IconClose, IconSend } from '@/components/SvgIcons' import SearchSuggestions from '@/components/SearchSuggestions' import SearchVoice from '@/components/SearchVoice' import Tooltip from '@/components/Tooltip' +import SearchTitle from '@/components/SearchTitle' import { ISearchCategory, ISearch, ISearchChild } from '@/interfaces/search' -import { useLocale, useTranslations } from 'next-intl' +import Welcome from '../Welcome' +import SearchOptions from '../SearchOptions' -export default function Search() { +interface Props { + selectedCategory: ISearchCategory +} + +export default function Search({ selectedCategory }: Readonly) { const locale = useLocale() const t = useTranslations('t') + const searchParams = useSearchParams() + const query = searchParams?.get('q') + const { - data, - category, - search, + setCategory, setSearch, searchUrl, setSearchUrl, - refSearchInput, - refSearchTabs, inputValue, setInputValue, + setTitleTrends, isMobileViewport, + refSearchInput, + refButtons, } = useSearch() const refSearchButton = useRef(null) - const [isValid, setIsValid] = useState(false) - const [isChild, setIsChild] = useState(false) + const [searchSource, setSearchSource] = useState() + const [isValid, setIsValid] = useState(false) + const [isFocused, setIsFocused] = useState(false) + const searchName = selectedCategory?.name_translated || selectedCategory?.name const handleResize = () => { if (refSearchInput) { @@ -39,62 +50,15 @@ export default function Search() { } } const handleFocus = () => { - refSearchInput && refSearchInput.current.focus() + if (refSearchInput.current) { + refSearchInput.current.focus() + } } const handleReset = () => { setInputValue('') setIsValid(false) handleResize() } - - const getSearchSource = (id: string) => { - const searchCategory = data?.find( - (item: ISearchCategory) => item.name === category, - ) - const source = searchCategory?.data?.find( - (item: ISearch) => normalizeId(item.name) === id, - ) - return source - } - const handleSearchSource = (id: string) => { - const search = getSearchSource(id) - - setSearch(id) - window.localStorage.setItem('search', id) - - const add = search?.additional ?? '' - - setSearchUrl(search?.action + inputValue + add) - - // options - setIsChild(search?.child ? true : false) - - !isMobileViewport && handleFocus() - } - - function renderOptions(id: string) { - const source = getSearchSource(id) - return ( -
- - -
- ) - } - - const handleValueChange = (event: any) => { - setInputValue(event.target.value) - setIsValid(event.target.value !== '' ? true : false) - - event.target.style.height = 'auto' - event.target.style.height = event.target.scrollHeight + 'px' - } const handleKeyEnter = (event: React.KeyboardEvent) => { if (event.key === 'Enter' && event.shiftKey) { // prevents Enter from skipping a line without Shift @@ -107,17 +71,24 @@ export default function Search() { } } } - const handleOptionChange = () => { - console.log( - data?.find((item: { name: any }) => item.name === category)?.data, + const handleSelectedSource = (id: string) => { + const source = selectedCategory.data?.find( + (item) => normalizeId(item.name) === id, ) + setSearchSource(source) + + setSearch(id) + window.localStorage.setItem('search', id) + + handleFocus() } + const handleValue = (event: any) => { + setInputValue(event.target.value) + setIsValid(event.target.value !== '') - // cache - useEffect(() => { - const storedSource = window.localStorage.getItem('search') - storedSource && handleSearchSource(storedSource) - }, [handleSearchSource]) + event.target.style.height = 'auto' + event.target.style.height = event.target.scrollHeight + 'px' + } // resize useEffect(() => { @@ -126,69 +97,125 @@ export default function Search() { } }, [isMobileViewport]) + // query + useEffect(() => { + query && setInputValue(query) + }, [query]) + + // url + useEffect(() => { + const additional = searchSource?.additional ?? '' + const action = searchSource?.action + + if (action) { + setSearchUrl(`${action}${encodeURIComponent(inputValue)}${additional}`) + } + }, [inputValue, searchSource]) + + // initial state + useEffect(() => { + if (selectedCategory) { + setCategory(selectedCategory?.name) + setTitleTrends(selectedCategory?.name_trends) + + // window.localStorage.setItem('category', selectedCategory?.name) + // const storedSource = window.localStorage.getItem('search') + + const sourceId = normalizeId(selectedCategory?.data[0]?.name) + + handleSelectedSource(sourceId) + refButtons?.current?.['button_' + sourceId]?.click() + } + }, [selectedCategory]) + + // focus + useEffect(() => { + if (!isFocused) { + setTimeout(() => { + handleFocus() + setIsFocused(true) + }, 0) + } + }, [isFocused, refSearchInput]) + return ( -
+
- + {/*
+ + +
*/} + +
+ {selectedCategory?.name == 'Home' ? ( + + ) : ( +

{searchName}

+ )} +
+
+

{t('componentWelcome.whatDoYouWant')}

+
+
+ + {/* Input */}
- {/* Placeholder */} -
- {/* {!isMobileViewport && ( -
{t('placeholder')}
- )} */} +
- {/* Input */} - -