diff --git a/README.md b/README.md index a8a9a6342d..5ba0e3cc89 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next ## Getting Started -First, set these envirnment variables in `env.local` file +First, set these envirnment variables in `env.local` file. ``` NEXT_PUBLIC_ENV= diff --git a/lang/ca.json b/lang/ca.json index 57add23c99..6510611ca5 100644 --- a/lang/ca.json +++ b/lang/ca.json @@ -353,6 +353,7 @@ "label.donation_status": "Estat de la donació", "label.donation_submitted": "Donació enviada", "label.donation_to": "Donació a", + "label.donate_to": "Donar a", "label.donation_to_the": "Donació a la", "label.done": "Fet", "label.donor": "Donant", @@ -379,6 +380,7 @@ "label.eg_we_are_a_dao_that_works": "per exemple. 'Som una organització autònoma descentralitzada que treballa en el desenvolupament d'aplicacions web3'", "label.elevate_projects": "Potencia projectes", "label.eligible_for_matching": "Elegible per l'emparellament", + "label.eligible_networks_for_matching": "Xarxes aptes per a la concordança QF", "label.email": "correu electrònic", "label.email_address": "Adreça electrònica", "label.enable_change": "Habilita el canvi", @@ -499,6 +501,7 @@ "label.got_it": "D'acord", "label.govern": "Governar", "label.governance": "Governança", + "label.go_back_and_check_network": "Torna enrere i assegura't que estàs a la xarxa correcta.", "label.go_back_to_donation_page": "Torna a la pàgina de donació", "label.go_back_to_modify_your_donation": "Torna a modificar la teva donació", "label.go_back_to_project_details": "Tornar als Detalls del Projecte", @@ -621,7 +624,9 @@ "label.lock_your_tokens": "Bloqueja els teus tokens", "label.look_for_the_share_and_get_rewarded": "Busca el botó 'Comparteix i guanya recompenses' per generar enllaços a pàgines específiques a tot el lloc de Giveth.", "label.make_a_recurring_donation_with": "Fes una donació recurrent amb ", - "label.make_it_anonymous": "Fes-ho anònim", + "label.make_it_anonymous": "Fes que la meva donació sigui anònima", + "label.transaction_detail": "Detall de la transacció", + "label.qr_code_error": "S'ha produït un error en generar el codi QR. Torneu-ho a provar.", "label.make_it_easier_for_donors_to_find_your_project": "Fes més fàcil que els donants trobin el teu projecte proporcionant una ubicació.", "label.make_it_unique_and_memorable_to_stand_out_from_other_projects": "Fes-ho únic i memorable per destacar entre altres projectes.", "label.make_sure_your_description_aligns_with_our": "Assegura't que la teva descripció s'aligna amb el nostre ", @@ -747,6 +752,10 @@ "label.photo_by": "Foto per", "label.please_confirm_your_email": "Si us plau, confirma el teu correu electrònic", "label.please_connect_your_wallet": "Si us plau, connecta la teva cartera", + "label.please_connect_your_wallet_to_win_givbacks": "Connecta la teva cartera per guanyar GIVbacks.", + "label.please_connect_your_wallet_to_win_givbacks_and_match": "Connecta la teva cartera per guanyar GIVbacks i igualar la teva donació en QF.", + "label.please_connect_your_wallet_to_match": "Connecteu la vostra cartera per igualar la vostra donació a QF", + "label.stellar_donations_arent_eligible": "Les donacions estel·lars no es poden igualar", "label.please_contact_support_team": "Si us plau, contacteu l'equip de suport.", "label.please_do_not_enter_exchange_deposit": "Si us plau, NO introduïu una adreça de dipòsit d'intercanvi, o els vostres fons podrien perdre's! Utilitzeu un compte que controleu en aquesta xarxa. Recomanem utilitzar Metamask.", "label.please_enter_full_link": "Introdueix el vincle complet", @@ -979,6 +988,7 @@ "label.start_referring!": "Comença a Recomanar!", "label.state": "Estat", "label.status": "Estat", + "label.stellar_is_not_eligible_for_matching": "Stellar no és elegible per aquesta ronda.", "label.streamed_rewards": "Recompenses en streaming", "label.streaming": "Streaming", "label.streaming_at_rate_of": "Transmetent a una taxa de", @@ -1018,6 +1028,7 @@ "label.support_giveth_with": "Doni suport a Giveth amb una donació a la Giveth DAO. El percentatge de donació seleccionat es prendrà del total de la quantitat de la vostra donació en el mateix token que esteu donant.", "label.support_upcoming_qf_round": "Doneu suport a les properes rondes i feu una donació al grup corresponent.", "label.switch_network": "Canviar xarxa", + "label.switch_to_supported": "Canvia a xarxes compatibles", "label.switch_to": "canvia a", "label.switch_to_archive_cards": "Canvia a Targetes d'arxiu", "label.switch_to_evm": "Canvia a la cartera EVM", @@ -1084,7 +1095,7 @@ "label.this_project_is_not_active": "Aquest projecte no està actiu.", "label.this_project_is_not_eligible_for_recurring_donations": "Aquest projecte no és elegible per a donacions recurrents", "label.this_project_only_accepts_donations_on": "Aquest projecte només accepta donacions a {chainName}.", - "label.this_project_only_accept_on": "Aquest projecte només accepta donacions a", + "label.this_project_doesnt_accept_on": "Aquest projecte no accepta donacions a", "label.this_projet_doesnt_receive_donations_on": "Aquest projecte no accepta donacions a {chainName}", "label.this_regenfarm_is_only_available_on_network": "Aquest RegenFarm només està disponible a {networkLabel}", "label.this_round": "aquesta ronda", @@ -1127,8 +1138,8 @@ "label.transaction_detail": "Detall de la transacció", "label.transaction_link": "Enllaç de la transacció", "label.transaction_status": "Estat de la transacció", - "label.trust_that_your_donations_will_make": "Assegura't que les teves donacions en criptomonedes donin suport a causes legítimes amb el nostre sistema de verificació descentralitzat.", - "label.try_donating_wuth_stellar": "Prova de donar amb Stellar.", + "label.trust_that_your_donations_will_make": "Confia que les teves donacions en cripto tindran un impacte amb el nostre sistema de verificació.", + "label.try_donating_with_stellar": "Prova de donar amb Stellar. No cal que connecteu la vostra cartera.", "label.try_removing_some_filters_keyword": "Intenta eliminar alguns filtres o utilitzar un altre mot clau.", "label.try_these": "Prova aquests", "label.try_to_use_this_structure": "Intenta utilitzar aquesta estructura com a guia a l'hora d'escriure la descripció", @@ -1334,11 +1345,13 @@ "page.about_us.desc.one": "Giveth és una comunitat centrada en la construcció del Futur de les Donacions utilitzant la tecnologia blockchain. La nostra intenció és donar suport i recompensar la finançament de béns públics creant accés obert, transparent i gratuït a les oportunitats de finançament innovadores en l'ecosistema d'Ethereum.", "page.about_us.desc.two": "Giveth està construint una cultura de donació que capacita i recompensa als qui donen, als projectes, a la societat i al món. El nostre objectiu és inspirar la nostra comunitat a participar en un ecosistema de suport col·lectiu, d'abundància i de creació de valor. Comproveu el nostre", "page.donate.bank_fees": "Comissions Bancàries", + "page.donate.donate_$_to_be_eligible": "Fes una donació de ${value} per ser elegible per a GIVbacks", + "page.donate.donate_$_to_get_matched": "Dona ${value} per igualar la teva donació", + "page.donate.donations_will_be_matched": "La donació serà igualada", + "page.donate.givbacks_eligible": "GIVbacks elegibles", "page.donate.matching_toast.bottom_invalid_p1": "Només donacions de més de", "page.donate.matching_toast.bottom_invalid_p2": "són elegibles per a l'aparellament.", "page.donate.matching_toast.bottom_valid": "Els fons de finançament es destinaran al projecte seleccionat després que acabi la ronda. Dona a més projectes per rebre més finançament!", - "page.donate.matching_toast.upper_invalid": "Fes que compti", - "page.donate.matching_toast.upper_valid": "Emparellament estimat", "page.donate.passport_toast.description.eligible": "La teva donació és elegible per ser emparellada! Després del", "page.donate.passport_toast.description.eligible_2": ", totes les donacions seran revisades per a la protecció contra frau i els fons d'emparellament seran enviats als projectes. Estigues atent a les notificacions :)", "page.donate.passport_toast.description.non_eligible": "Obtén el teu emparellament de donació amb finançament quadràtic!\nComproveu la vostra elegibilitat QF abans", @@ -1347,6 +1360,16 @@ "page.donate.passport_toast.title.non_eligible": "No et perdis l'emparellament!", "page.donate.title": "Donar", "page.donate.zero_fees": "Sense Comissions", + "page.donate.makes_you_eligible_for_givbacks": "${value} et fan elegible per a GIVbacks", + "page.donate.unlocks_matching_funds": "${value} desbloquegen fons coincidents", + "page.donate.donations_will_be_matched": "La donació serà igualada", + "page.donate.project_not_eligible_for_qf": "El projecte no és elegible per a la concordança QF.", + "page.donate.network_not_eligible_for_qf": "Les donacions de {network} no són aptes per coincidir", + "page.donate.givbacks_eligible": "GIVbacks elegibles", + "page.donate.project_not_givbacks_eligible": "El projecte no és elegible per a GIVbacks", + "page.donate.title": "Donar", + "page.donate.token_not_givbacks_eligible": "{token} no és apte per a GIVbacks", + "page.donate.zero_fees": "Sense Comissions", "page.engage.discord.desc": "Uneix-te a la conversa! Discord és on el nostre equip es comunica. Presenta't, dóna'ns comentaris, descobreix com contribuir o simplement saluda!", "page.engage.discourse.desc": "El fòrum de Giveth és on creem discursos sobre propostes noves i existents. Compartim idees sobre desenvolupament i governança, cultivant discussions sobre temes importants al voltant del nostre equip i la comunitat.", "page.engage.github.desc": "Tens habilitats de desenvolupament? Comprova el nostre Github! Sempre benvingut a nous col·laboradors. Si us plau, uneix-te a un dels nostres canals de dev a Discord per saludar-nos!", @@ -1644,24 +1667,22 @@ "project.givback_toast.description.non_verified_owner_rejected_2": " o al suport de Discord per a més instruccions.", "project.givback_toast.description.non_verified_owner_submitted": "Notícies emocionants! La teva sol·licitud ha estat enviada i està a la cua per ser revisada pel nostre equip de revisió d'elegibilitat per a GIVbacks. Et respondrem en un termini d'1-2 setmanes.", "project.givback_toast.description.non_verified_public": "Actualment, els GIVbacks només s'atorguen per donacions fetes a projectes elegibles per a GIVbacks a Ethereum. La teva contribució segueix sent important, fins i tot si no genera GIVbacks!", - "project.givback_toast.description.verified_owner": "Impulsa el teu projecte per augmentar la quantitat de GIVbacks que reben els teus donants a Ethereum i augmentar la seva visibilitat entre altres projectes.", - "project.givback_toast.description.verified_owner.note": "Com a propietari d'aquest projecte, no rebràs GIVbacks per donar-hi.", - "project.givback_toast.description.verified_owner_not_eligible": "El teu projecte ha estat avalat pels Verificadors de Giveth i ara pot beneficiar-se de GIVpower. Fes stake i bloqueja els teus tokens GIV per impulsar aquest projecte i fer-lo més visible a la pàgina de projectes. No obstant això, donar a aquest projecte no generarà GIVbacks per als donants.", - "project.givback_toast.description.verified_public": "Les donacions a Ethereum a projectes elegibles per a GIVbacks són recompensades amb GIV. Impulsa aquest projecte per augmentar el seu percentatge de recompenses i fer-lo més visible a la pàgina de projectes!", - "project.givback_toast.description.verified_public_not_eligible": "{stakeLock} els teus tokens GIV per obtenir GIVpower. Impulsa aquest projecte per fer-lo més visible a la pàgina de projectes! Tingues en compte que, tot i que aquest projecte és elegible per ser impulsat amb GIVpower, no generarà GIVbacks per als seus donants.", - "project.givback_toast.title.non_verified_owner": "El teu projecte està creant o donant suport a béns públics?", - "project.givback_toast.title.non_verified_owner_cancelled": "Estat Cancel·lat", + "project.givback_toast.description.verified_owner": "Potencia el teu projecte per augmentar el seu percentatge de GIVbacks i ajudar-lo a aparèixer més amunt a la pàgina de projectes!", + "project.givback_toast.description.verified_public": "Les donacions a Ethereum a projectes elegibles per a GIVbacks són recompensades amb GIV. Impulsa aquest projecte per augmentar el seu percentatge de recompenses i fer-lo més visible a la pàgina de projectes!", "project.givback_toast.title.non_verified_owner": "El teu projecte està creant o donant suport a béns públics?", + "project.givback_toast.description.verified_public": "Les donacions de ${value} o més són elegibles per a GIVback. Potencia aquest projecte per augmentar el seu percentatge de recompenses i la seva visibilitat a la pàgina de projectes!", + "project.givback_toast.description.verified_owner_not_eligible": "El teu projecte ha estat avalat pels Verificadors de Giveth i ara pot beneficiar-se de GIVpower. Fes stake i bloqueja els teus tokens GIV per impulsar aquest projecte i fer-lo més visible a la pàgina de projectes. No obstant això, donar a aquest projecte no generarà GIVbacks per als donants.", + "project.givback_toast.title.non_verified_owner": "El teu projecte està creant o donant suport a béns públics?", + "project.givback_toast.title.non_verified_owner_cancelled": "Estat Cancel·lat", "project.givback_toast.title.non_verified_owner_deactive": "Mode Desactivat", "project.givback_toast.title.non_verified_owner_draft": "Publica el teu projecte avui!", "project.givback_toast.title.non_verified_owner_incomplete": "Sol·licitud Incompleta", "project.givback_toast.title.non_verified_owner_rejected": "No vam poder aprovar el teu projecte com a elegible per a GIVbacks", "project.givback_toast.title.non_verified_owner_submitted": "Sol·licitud enviada", "project.givback_toast.title.non_verified_public": "Per què no hi ha GIVbacks?", - "project.givback_toast.title.verified_owner_1": "Els donants són recompensats amb fins a ", - "project.givback_toast.title.verified_owner_2": " del valor de la donació!", - "project.givback_toast.title.verified_owner_not_eligible": "El teu projecte ha estat avalat", "project.givback_toast.title.verified_public_1": "Rep recompenses de fins a ", - "project.givback_toast.title.verified_public_2": " del valor de la teva donació!", + "project.givback_toast.title.verified_owner": "Les donacions de {value}$ o més són elegibles per a reemborsaments de fins a un {percent}%!", + "project.givback_toast.title.verified_owner_not_eligible": "El teu projecte ha estat avalat", + "project.givback_toast.title.verified_public_2": " del valor de la teva donació!", "project.givback_toast.title.verified_public_not_eligible": "Impulsa aquest projecte amb GIVpower!", "projects_all": "Tots els Projectes", "projects_all_desc": "SUPORT A PROJECTES GLOBALS DE BÉS PÚBLICS, SOSTENIBILITAT I REGENERACIÓ AMB CRYPTODONACIONS", diff --git a/lang/en.json b/lang/en.json index e586598b53..dd77cddd15 100644 --- a/lang/en.json +++ b/lang/en.json @@ -354,6 +354,7 @@ "label.donation_submitted": "Donation submitted", "label.donation_to": "Donation to", "label.donation_to_the": "Donation to the", + "label.donate_to": "Donate to", "label.done": "Done", "label.donor": "Donor", "label.donors_to_higher_ranked_projects": "Donors to higher ranked projects get more GIVbacks.", @@ -379,6 +380,7 @@ "label.eg_we_are_a_dao_that_works": "eg. 'We are a decentralized autonomous organization that works toward the development of web3 applications'", "label.elevate_projects": "Elevate Projects", "label.eligible_for_matching": "Eligible for Matching", + "label.eligible_networks_for_matching": "Eligible networks for QF matching", "label.email": "email", "label.email_address": "Email Address", "label.enable_change": "Enable Change", @@ -410,7 +412,7 @@ "label.filters": "Filters", "label.find_awesome_projects_on_giveth": "Find awesome projects on Giveth", "label.finish": "Finish", - "label.fireup_your_community_to_use_givpower": "Fire up your community to use GIVpower to improve your rank.", + "label.fireup_your_community_to_use_givpower": "Ask your community to boost your project", "label.first_name": "First name", "label.flowrate_change": "Flowrate Change", "label.flow_rate": "Stream Rate", @@ -499,6 +501,7 @@ "label.got_it": "Got it", "label.govern": "Govern", "label.governance": "Governance", + "label.go_back_and_check_network": "Go back and make sure you're on the right network.", "label.go_back_to_donation_page": "Go back to donation page", "label.go_back_to_modify_your_donation": "Go back to modify your donation", "label.go_back_to_project_details": "Go back to Project Details", @@ -526,7 +529,7 @@ "label.home": "Home", "label.how?": "How?", "label.how_can_we_help_you": "How can we help you?", - "label.how_does_givpower_work": "How does GIVpower work?", + "label.how_does_givpower_work": "How does boosting work?", "label.how_does_this_work": "How does this work?", "label.how_do_you_want_to_donate": "How do you want to donate?", "label.how_it_works": "How It Works", @@ -548,7 +551,7 @@ "label.if_you_wrap_for_one_month": "If you wrap for 1 month:", "label.ill_raise_and_receive_funds_on_all_chains": "I’ll raise & receive funds on Mainnet, Gnosis Chain, Polygon, Celo and Optimism networks with the same address.", "label.ill_receive_funds_on_this_address": "I’ll receive fund on this address", - "label.imagine_a_world_where": "Imagine a world where you could support public goods and get rewarded", + "label.imagine_a_world_where": "Discover decentralized project curation with GIVpower boosting", "label.impact": "Impact", "label.in": "in", "label.include_media_such_as_videos_and_photos_to_show_off_the_work": "Include media such as videos and photos to show off the work you’re doing.", @@ -621,7 +624,11 @@ "label.lock_your_tokens": "Lock your tokens", "label.look_for_the_share_and_get_rewarded": "Look for the 'Share & get rewarded' button to generate links to specific pages across the Giveth site.", "label.make_a_recurring_donation_with": "Make a recurring donation with ", - "label.make_it_anonymous": "Make it anonymous", + "label.make_it_anonymous": "Make my donation anonymous", + "label.view_all_projects": "View all projects", + "label.sanctioned_wallet": "Sanctioned Address Detected !!", + "label.sanctioned_wallet_message_part1": "This address has been found on the USA", + "label.sanctioned_wallet_message_part2": "sanctioned list.\nUnfortunately, Endaoment does not permit addresses on the\nOFAC sanction list to donate to projects delivered by\nEndaoment. Check out another project to donate to. ", "label.make_it_easier_for_donors_to_find_your_project": "Make it easier for donors to find your project by providing a location.", "label.make_it_unique_and_memorable_to_stand_out_from_other_projects": "Make it unique and memorable to stand out from other projects.", "label.make_sure_your_description_aligns_with_our": "Make sure your description aligns with our ", @@ -747,6 +754,10 @@ "label.photo_by": "Photo by", "label.please_confirm_your_email": "Please confirm your email", "label.please_connect_your_wallet": "Please connect your wallet", + "label.please_connect_your_wallet_to_win_givbacks": "Connect your wallet to win GIVbacks.", + "label.please_connect_your_wallet_to_win_givbacks_and_match": "Connect your wallet to win GIVbacks and match your donation in QF.", + "label.please_connect_your_wallet_to_match": "Connect your wallet to match your donation in QF", + "label.stellar_donations_arent_eligible": "Stellar donations aren’t eligible for matching", "label.please_contact_support_team": "Please contact support team.", "label.please_do_not_enter_exchange_deposit": "Please DO NOT enter an exchange deposit address, or your funds maybe lost! Use an account you control on this network. We recommend using Metamask.", "label.please_enter_full_link": "Please enter full link", @@ -979,6 +990,7 @@ "label.start_referring!": "Start Referring!", "label.state": "State", "label.status": "Status", + "label.stellar_is_not_eligible_for_matching": "Stellar is not eligible for this round.", "label.streamed_rewards": "Streamed Rewards", "label.streaming": "Streaming", "label.streaming_at_rate_of": "Streaming at a rate of", @@ -1018,6 +1030,7 @@ "label.support_giveth_with": "Support Giveth with a donation to the Giveth DAO. The selected donation percentage will be taken from the total of your donation amount in the same token you are donating.", "label.support_upcoming_qf_round": "Support upcoming rounds and donate to the matching pool.", "label.switch_network": "Switch Network", + "label.switch_to_supported": "Switch to supported networks", "label.switch_to": "switch to", "label.switch_to_archive_cards": "Switch to Archive Cards", "label.switch_to_evm": "Switch to EVM wallet", @@ -1052,7 +1065,7 @@ "label.the_givers_are": "The Givers are a limited collection of 1,250 artworks inspired by the Giveth Galaxy. Each NFT tells a unique story of Giveth, in its own fun and vibrant style.", "label.the_givgarden_is_the_descentralized_gov_platform": "The GIVgarden is the decentralized governance platform for the GIVeconomy. Increase your GIVstream when you wrap GIV to vote.", "label.the_giv_garden_empowers_the_giv_community": "The GIVgarden empowers the Giveth community to coordinate around shared resources from the bottom up.", - "label.the_higher_your_rank_the_more_givback": "The higher your rank, the more GIVbacks your donors will receive.", + "label.the_higher_your_rank_the_more_givback": "The higher your rank, the better the GIVbacks rewards for donors.", "label.the_launch_of_the": "The launch of the", "label.the_longer_you_lock_the_greater_your_reward": "The longer you lock, the greater your rewards.", "label.the_min_apr_for_staked_not_locked_giv": "The minimum APR for staked (not locked) GIV. Lock your GIV to increase your rewards.", @@ -1084,7 +1097,7 @@ "label.this_project_is_not_active": "This project is not active.", "label.this_project_is_not_eligible_for_recurring_donations": "This project is not eligible for recurring donations.", "label.this_project_only_accepts_donations_on": "This project only accepts donations on {chainName}.", - "label.this_project_only_accept_on": "This project only accept donations on", + "label.this_project_doesnt_accept_on": "Project doesn’t accept donation on", "label.this_projet_doesnt_receive_donations_on": "This project does not accept donations on {chainName}", "label.this_regenfarm_is_only_available_on_network": "This RegenFarm is only available on {networkLabel}", "label.this_round": "this round", @@ -1102,7 +1115,7 @@ "label.tokens": "Tokens", "label.token_list": "Token List", "label.token_stream_rewards": "{rewardTokenSymbol} stream rewards", - "label.topranked_projects_will_eventually_get_funding": "Top-ranked projects will eventually get funding from the Giveth Matching Pool.", + "label.topranked_projects_will_eventually_get_funding": "Don't forget to boost your own project too!", "label.top_up_before": "Top-up before", "label.top_up_stream_balance": "Top-up stream balance", "label.top_up_your_stream_balance_within": "Top-up your Stream balance within", @@ -1127,8 +1140,8 @@ "label.transaction_detail": "Transaction detail", "label.transaction_link": "Transaction link", "label.transaction_status": "Transaction Status", - "label.trust_that_your_donations_will_make": "Ensure your crypto donations support legitimate causes with our decentralized verification system.", - "label.try_donating_wuth_stellar": "Try donating with Stellar.", + "label.trust_that_your_donations_will_make": "Trust that your crypto donations will make an impact with our verification system.", + "label.try_donating_with_stellar": "Try donating with Stellar. You don’t need to connect your wallet.", "label.try_removing_some_filters_keyword": "Try removing some filters or using another keyword.", "label.try_these": "Try these", "label.try_to_use_this_structure": "Try to use this structure as a guide when writing the description", @@ -1153,7 +1166,7 @@ "label.user_your_givpower_to_support_verified_projects": "Use your GIVpower to support vouched projects on Giveth while earning rewards.", "label.use_as_profile_picture": "Use as profile picture", "label.use_a_bank_transfer_or_credit_Card": "Use a bank transfer or credit card to purchase crypto and deposit it directly into your web3 wallet.", - "label.use_giv_to_boost_projects": "Use GIV to boost projects to new heights!", + "label.use_giv_to_boost_projects": "GIVpower is your Giveth governance power! Use it to boost projects or vote on Giveth DAO proposals.", "label.use_giv_to_vote": "Use GIV to vote on funding proposals in the GIVgarden.", "label.use_relevant_keywords_that_describe_your_project": "Use relevant keywords that describe your project.", "label.use_your_bank_account_or_credit_card_to_send_crypto_to_your_wallet": "Use your bank account or credit card to send crypto to your web3 wallet, then donate to support projects!", @@ -1224,7 +1237,7 @@ "label.why_dont_i_have_givbacks": "Why don't I have GIVbacks?", "label.why_giveth": "Why Giveth?", "label.will_be_unlisted_until": "will be 'unlisted' until reviewed by our team", - "label.winwin_for_givers_and_projects": "Win-win for GIVers & Projects", + "label.winwin_for_givers_and_projects": "Win-win for Givers & Projects", "label.withdraw": "Withdraw", "label.withdrawal_confirmed": "Withdrawal confirmed", "label.withdrawing": "Withdrawing", @@ -1334,11 +1347,13 @@ "page.about_us.desc.one": "Giveth is a community focused on Building the Future of Giving using blockchain technology. Our intention is to support and reward the funding of public goods by creating open, transparent and free access to the revolutionary funding opportunities available within the Ethereum ecosystem.", "page.about_us.desc.two": "Giveth is building a culture of giving that empowers and rewards those who give -- to projects, to society, and to the world. We aim to inspire our community to participate in an ecosystem of collective support, abundance and value-creation. Check out our", "page.donate.bank_fees": "Bank Fees", + "page.donate.donate_$_to_be_eligible": "Donate ${value} to be eligible for GIVbacks", + "page.donate.donate_$_to_get_matched": "Donate ${value} to get your donation matched", + "page.donate.donations_will_be_matched": "Donation will be matched", + "page.donate.givbacks_eligible": "GIVbacks eligible", "page.donate.matching_toast.bottom_invalid_p1": "Only donations more than", "page.donate.matching_toast.bottom_invalid_p2": "are eligible for matching.", "page.donate.matching_toast.bottom_valid": "Matching funds will be sent to the selected project after the round ends. Donate to more projects to receive higher matching!", - "page.donate.matching_toast.upper_invalid": "Make it count", - "page.donate.matching_toast.upper_valid": "Estimated matching", "page.donate.passport_toast.description.eligible": "Your donation is eligible to be matched! After the", "page.donate.passport_toast.description.eligible_2": ", all donations will be reviewed for fraud protection and matching funds will be sent to the projects. Stay tuned for notifications :)", "page.donate.passport_toast.description.non_eligible": "Get your donation matched with quadratic funding!\nCheck your QF Eligibility before", @@ -1347,6 +1362,16 @@ "page.donate.passport_toast.title.non_eligible": "Don’t miss out on matching!", "page.donate.title": "Donate", "page.donate.zero_fees": "Zero Fees", + "page.donate.makes_you_eligible_for_givbacks": "${value} makes you eligible for GIVbacks", + "page.donate.unlocks_matching_funds": "${value} unlocks matching funds", + "page.donate.donations_will_be_matched": "Donation will be matched", + "page.donate.project_not_eligible_for_qf": "Project is not eligible for QF matching.", + "page.donate.network_not_eligible_for_qf": "{network} donations aren’t eligible for matching", + "page.donate.givbacks_eligible": "GIVbacks eligible", + "page.donate.project_not_givbacks_eligible": "Project is not GIVbacks eligible", + "page.donate.title": "Donate", + "page.donate.token_not_givbacks_eligible": "{token} is not eligible for GIVbacks", + "page.donate.zero_fees": "Zero Fees", "page.engage.discord.desc": "Join the conversation! Discord is where our team communicates. Introduce yourself, give us feedback, find out how to contribute or just say hello!", "page.engage.discourse.desc": "The Giveth forum is where we create discourse around new and existing proposals. We share ideas involving development and governance, cultivating discussions about important topics around our team and community.", "page.engage.github.desc": "Got some developer skills? Check out our Github! We always welcome new contributors. Please also join one of our dev channels in Discord to say hello!", @@ -1644,23 +1669,21 @@ "project.givback_toast.description.non_verified_owner_rejected_2": " or Discord support for more instructions.", "project.givback_toast.description.non_verified_owner_submitted": "Exciting news! Your application has been submitted and is in the queue for review by our GIVbacks Eligibility review team. We will get back to you with a response within 1-2 weeks.", "project.givback_toast.description.non_verified_public": "GIVbacks are currently only awarded for donations made to GIVbacks Eligible projects on Ethereum. Your contribution still matters, even if it doesn't generate GIVbacks!", - "project.givback_toast.description.verified_owner": "Boost your project to increase the amount of GIVbacks your donors on Ethereum receive and increase its visibility among other projects!", - "project.givback_toast.description.verified_owner.note": "As the owner of this project, you won’t get GIVbacks for donating to it.", - "project.givback_toast.description.verified_owner_not_eligible": "Your project has been vouched for by Giveth Verifiers and can now benefit from GIVpower! Stake and lock your GIV tokens to boost this project and make it more visible on the projects page. However, donating to this project won't yield GIVbacks to donors.", - "project.givback_toast.description.verified_public": "Ethereum donations to GIVbacks Eligible projects are rewarded with GIV. Boost this project to increase its rewards percentage and make it more visible on the projects page!", - "project.givback_toast.description.verified_public_not_eligible": "{stakeLock} your GIV tokens to get GIVpower. Boost this project make it more visible on the projects page! Note that while this project is eligible to be boosted with GIVpower, it will not yield GIVbacks to it's donors.", - "project.givback_toast.title.non_verified_owner": "Is your project creating or supporting public goods?", - "project.givback_toast.title.non_verified_owner_cancelled": "Project Cancelled", + "project.givback_toast.description.verified_owner": "Boost your project to increase its GIVbacks percentage and help it appear higher on the projects page!", + "project.givback_toast.description.verified_public": "Donations of ${value} or more are eligible for GIVbacks. Boost this project to increase its rewards percentage and visibility on the projects page!", + "project.givback_toast.description.verified_owner_not_eligible": "Your project has been vouched for by Giveth Verifiers and can now benefit from GIVpower! Stake and lock your GIV tokens to boost this project and make it more visible on the projects page. However, donating to this project won't yield GIVbacks to donors.", + "project.givback_toast.title.non_verified_owner": "Is your project creating or supporting public goods?", + "project.givback_toast.description.verified_public_not_eligible": "{stakeLock} your GIV tokens to get GIVpower. Boost this project make it more visible on the projects page! Note that while this project is eligible to be boosted with GIVpower, it will not yield GIVbacks to it's donors.", + "project.givback_toast.title.non_verified_owner_cancelled": "Project Cancelled", "project.givback_toast.title.non_verified_owner_deactive": "Project Deactivated", "project.givback_toast.title.non_verified_owner_draft": "Publish your project today!", "project.givback_toast.title.non_verified_owner_incomplete": "Application incomplete", "project.givback_toast.title.non_verified_owner_rejected": "We couldn't approve your project as GIVbacks eligible", "project.givback_toast.title.non_verified_owner_submitted": "Application submitted", "project.givback_toast.title.non_verified_public": "Why no GIVbacks?", - "project.givback_toast.title.verified_owner_1": "Donors get rewarded with up to ", - "project.givback_toast.title.verified_owner_2": " of the donation value!", - "project.givback_toast.title.verified_owner_not_eligible": "Your project has been Vouched for", "project.givback_toast.title.verified_public_1": "Get rewarded with up to ", + "project.givback_toast.title.verified_owner_not_eligible": "Your project has been Vouched for", + "project.givback_toast.title.verified_owner": "Donations of ${value} or more qualify for GIVbacks with up to {percent}%!", "project.givback_toast.title.verified_public_2": " of your donation value!", "project.givback_toast.title.verified_public_not_eligible": "Boost this project with GIVpower!", "projects_all": "All Projects", diff --git a/lang/es.json b/lang/es.json index 565d6068c4..9b243e9797 100644 --- a/lang/es.json +++ b/lang/es.json @@ -353,6 +353,7 @@ "label.donation_status": "Estado de la donación", "label.donation_submitted": "Donación enviada", "label.donation_to": "Donación a", + "label.donate_to": "Donar a", "label.donation_to_the": "Donación a la", "label.done": "Listo", "label.donor": "Donante", @@ -379,6 +380,7 @@ "label.eg_we_are_a_dao_that_works": "Ej. \"Somos una organización autónoma descentralizada que trabaja en el desarrollo de aplicaciones web3\"", "label.elevate_projects": "Eleva proyectos", "label.eligible_for_matching": "Elegible para Emparejamiento", + "label.eligible_networks_for_matching": "Redes elegibles para la asignación de QF", "label.email": "Email", "label.email_address": "Dirección de Email", "label.enable_change": "Ayuda al Cambio", @@ -499,6 +501,7 @@ "label.got_it": "Entendido", "label.govern": "Gobernar", "label.governance": "Gobernanza", + "label.go_back_and_check_network": "Vuelve atrás y asegúrate de que estás en la red correcta.", "label.go_back_to_donation_page": "Vuelve a la pagina de donación", "label.go_back_to_modify_your_donation": "Regresar para modificar tu donación", "label.go_back_to_project_details": "Vuelve a Detalles del Proyecto", @@ -621,7 +624,7 @@ "label.lock_your_tokens": "Lock tus tokens", "label.look_for_the_share_and_get_rewarded": "Busca el botón 'Compartir y obtener recompensas' para generar enlaces a páginas específicas en todo el sitio de Giveth.", "label.make_a_recurring_donation_with": "Haz una donación recurrente con ", - "label.make_it_anonymous": "Hazlo anónimo", + "label.make_it_anonymous": "Hacer mi donación anónimo", "label.make_it_easier_for_donors_to_find_your_project": "Has que sea fácil encontrar tu proyecto para los donantes proporcionando una ubicación.", "label.make_it_unique_and_memorable_to_stand_out_from_other_projects": "Hazlo único y memorable para destacar entre otros proyectos.", "label.make_sure_your_description_aligns_with_our": "Asegúrate de que tu descripción esté alineada con nuestro ", @@ -747,6 +750,10 @@ "label.photo_by": "Foto por", "label.please_confirm_your_email": "Por favor confirma tu e-mail", "label.please_connect_your_wallet": "Por favor conecta tu billetera", + "label.please_connect_your_wallet_to_win_givbacks": "Conecta tu billetera para ganar GIVbacks.", + "label.please_connect_your_wallet_to_win_givbacks_and_match": "Conecta tu billetera para ganar GIVbacks e igualar tu donación en QF.", + "label.please_connect_your_wallet_to_match": "Conecta tu billetera para igualar tu donación en QF", + "label.stellar_donations_arent_eligible": "Las donaciones de Stellar no son elegibles para igualación", "label.please_contact_support_team": "Por favor contacta al equipo de soporte.", "label.please_do_not_enter_exchange_deposit": "¡Por favor, NO introduzcas una dirección de depósito de intercambio, o podrías perder tus fondos! Usa una cuenta que controles en esta red. Recomendamos usar Metamask.", "label.please_enter_full_link": "Por favor, introduzca el enlace completo", @@ -979,6 +986,7 @@ "label.start_referring!": "¡Comienza a referir!", "label.state": "Estado", "label.status": "Estado", + "label.stellar_is_not_eligible_for_matching": "Stellar no es elegible para esta ronda.", "label.streamed_rewards": "Recompensas en streaming", "label.streaming": "Transmitiendo", "label.streaming_at_rate_of": "Transmitiendo a una tasa de", @@ -1018,6 +1026,7 @@ "label.support_giveth_with": "Apoya a Giveth con una donación a la Giveth DAO.El porcentaje de donación seleccionado se tomará del total de la cantidad de tu donación en el mismo token que estás donando.", "label.support_upcoming_qf_round": "Apoye las próximas rondas y done al grupo correspondiente.", "label.switch_network": "Cambiar Red", + "label.switch_to_supported": "Cambiar a redes compatibles", "label.switch_to": "cambiar a", "label.switch_to_archive_cards": "Cambiar a tarjetas de archivo", "label.switch_to_evm": "Cambiar a cartera EVM", @@ -1084,7 +1093,7 @@ "label.this_project_is_not_active": "Este proyecto no esta activo.", "label.this_project_is_not_eligible_for_recurring_donations": "Este proyecto no es elegible para donaciones recurrentes", "label.this_project_only_accepts_donations_on": "Este proyecto solo acepta donaciones en {chainName}.", - "label.this_project_only_accept_on": "Este proyecto acepta donaciones en", + "label.this_project_doesnt_accept_on": "Este proyecto no acepta donaciones en", "label.this_projet_doesnt_receive_donations_on": "Este proyecto no acepta donaciones en {chainName}", "label.this_regenfarm_is_only_available_on_network": "Este RegenFarm solo esta disponible en {networkLabel}", "label.this_round": "esta ronda", @@ -1127,8 +1136,8 @@ "label.transaction_detail": "Detalles de la transacción", "label.transaction_link": "Enlace de la transacción", "label.transaction_status": "Estado de Transacción", - "label.trust_that_your_donations_will_make": "Asegúrate de que tus donaciones en criptomonedas apoyen causas legítimas con nuestro sistema de verificación descentralizado.", - "label.try_donating_wuth_stellar": "Intenta donar con Stellar.", + "label.trust_that_your_donations_will_make": "Confía en que tus donaciones en criptomonedas tendrán un impacto con nuestro sistema de verificación.", + "label.try_donating_with_stellar": "Intenta donar con Stellar. No necesitas conectar tu billetera.", "label.try_removing_some_filters_keyword": "Intenta eliminar algunos filtros o usar otra palabra clave.", "label.try_these": "Intenta estos", "label.try_to_use_this_structure": "Intenta usar esta estructura como guía al momento de escribir la descripción", @@ -1334,19 +1343,31 @@ "page.about_us.desc.one": "Giveth es una comunidad enfocada en construir el Futuro de las Donaciones utilizando la tecnología blockchain. Nuestra intención es apoyar y recompensar la financiación de bienes públicos creando un acceso abierto, transparente y gratuito a las oportunidades de financiación innovadoras en el ecosistema de Ethereum.", "page.about_us.desc.two": "Giveth está construyendo una cultura de donación que empodera y recompensa a los que donan, a los proyectos, a la sociedad y al mundo. Nuestro objetivo es inspirar a nuestra comunidad a participar en un ecosistema de apoyo colectivo, de abundancia y creación de valor. Echa un vistazo a nuestro", "page.donate.bank_fees": "Comisiones Bancarias", + "page.donate.donate_$_to_be_eligible": "Dona ${value} para ser elegible para GIVbacks", + "page.donate.donate_$_to_get_matched": "Dona ${value} para que tu donación sea igualada", + "page.donate.donations_will_be_matched": "La donación será igualada", + "page.donate.givbacks_eligible": "Elegibles para GIVbacks", "page.donate.matching_toast.bottom_invalid_p1": "Sólo las donaciones superiores a", "page.donate.matching_toast.bottom_invalid_p2": "son subvencionables.", "page.donate.matching_toast.bottom_valid": "Los fondos de emparejamiento se enviarán al proyecto seleccionado después de que termine la ronda. ¡Dona a más proyectos para recibir un mayor emparejamiento!", - "page.donate.matching_toast.upper_invalid": "Haz que cuente", - "page.donate.matching_toast.upper_valid": "Estimado del monto complementado", "page.donate.passport_toast.description.eligible": "¡Tu donación es elegible para ser complementada! Después de la", "page.donate.passport_toast.description.eligible_2": ", todas las donaciones serán revisadas para protección contra fraudes y los fondos de complementarios se enviarán a los proyectos. ¡Mantente atento a las notificaciones! :)", "page.donate.passport_toast.description.non_eligible": "¡Haz que tu donación sea complementada con financiamiento cuadrático!\nCompruebe su elegibilidad QF antes de", "page.donate.passport_toast.description.not_connected": "¡Haz que tu donación sea complementada con financiamiento cuadrático! Verifica tu Gitcoin Passport antes de", "page.donate.passport_toast.title.eligible": "Financiamiento Cuadrático", "page.donate.passport_toast.title.non_eligible": "¡No te pierdas la oportunidad!", + "page.donate.project_not_givbacks_eligible": "El proyecto no es elegible para GIVbacks", "page.donate.title": "Donar", + "page.donate.token_not_givbacks_eligible": "{token} no es elegible para GIVbacks", "page.donate.zero_fees": "Sin Comisiones", + "page.donate.makes_you_eligible_for_givbacks": "${value} te hacen elegible para recibir GIVbacks", + "page.donate.unlocks_matching_funds": "${value} desbloquean fondos equivalentes", + "page.donate.donations_will_be_matched": "La donación será igualada", + "page.donate.project_not_eligible_for_qf": "El proyecto no es elegible para la financiación QF.", + "page.donate.network_not_eligible_for_qf": "Las donaciones de {network} no son elegibles para igualar", + "page.donate.givbacks_eligible": "Elegibles para GIVbacks", + "page.donate.project_not_givbacks_eligible": "El proyecto no es elegible para GIVbacks", + "page.donate.token_not_givbacks_eligible": "{token} no es elegible para GIVbacks", "page.engage.discord.desc": "¡Únete a la conversación! Nuestro equipo se comunica en Discord. Preséntate, danos retroalimentación, descubre cómo contribuir o ¡sólo saluda!", "page.engage.discourse.desc": "El foro de Giveth es donde creamos debates alrededor de propuestas existentes y nuevas. Compartimos ideas sobre el desarrollo y la gobernanza, desarrollando debates sobre temas importantes en torno a nuestro equipo y comunidad.", "page.engage.github.desc": "¿Sabes de desarrollo? ¡Entra a nuestro Github! Las puertas siempre están abiertas para nuevos colaboradores. ¡También te invitamos a unirte a nuestro canal de devs en Discord!", @@ -1644,12 +1665,11 @@ "project.givback_toast.description.non_verified_owner_rejected_2": " o al soporte de Discord para más instrucciones.", "project.givback_toast.description.non_verified_owner_submitted": "¡Noticias emocionantes! Tu solicitud ha sido enviada y está en la cola para ser revisada por nuestro equipo de revisión de elegibilidad para GIVbacks. Te responderemos en un plazo de 1-2 semanas.", "project.givback_toast.description.non_verified_public": "Actualmente, los GIVbacks solo se otorgan por donaciones hechas a proyectos elegibles para GIVbacks en Ethereum. ¡Tu contribución sigue siendo importante, incluso si no genera GIVbacks!", - "project.givback_toast.description.verified_owner": "Impulsa tu proyecto para aumentar la cantidad de GIVbacks que reciben tus donantes en Ethereum y aumentar su visibilidad entre otros proyectos.", - "project.givback_toast.description.verified_owner.note": "Como propietario de este proyecto, no recibirás GIVbacks por donar a él.", - "project.givback_toast.description.verified_owner_not_eligible": "Tu proyecto ha sido avalado por los Verificadores de Giveth y ahora puede beneficiarse de GIVpower. Haz stake y bloquea tus tokens GIV para impulsar este proyecto y hacerlo más visible en la página de proyectos. Sin embargo, donar a este proyecto no generará GIVbacks para los donantes.", - "project.givback_toast.description.verified_public": "Las donaciones en Ethereum a proyectos elegibles para GIVbacks son recompensadas con GIV. ¡Impulsa este proyecto para aumentar su porcentaje de recompensas y hacerlo más visible en la página de proyectos!", - "project.givback_toast.description.verified_public_not_eligible": "{stakeLock} tus GIV tokens para obtener GIVpower. ¡Impulsa este proyecto para hacerlo más visible en la página de proyectos! Ten en cuenta que aunque este proyecto es elegible para ser impulsado con GIVpower, no generará GIVbacks para sus donantes.", - "project.givback_toast.title.non_verified_owner": "¿Tu proyecto está creando o apoyando bienes públicos?", + "project.givback_toast.description.verified_owner": "Impulsa tu proyecto para aumentar la cantidad de GIVbacks que reciben tus donantes en Ethereum y aumentar su visibilidad entre otros proyectos.", + "project.givback_toast.description.verified_owner_not_eligible": "Tu proyecto ha sido avalado por los Verificadores de Giveth y ahora puede beneficiarse de GIVpower. Haz stake y bloquea tus tokens GIV para impulsar este proyecto y hacerlo más visible en la página de proyectos. Sin embargo, donar a este proyecto no generará GIVbacks para los donantes.", + "project.givback_toast.description.verified_public": "Las donaciones de ${value} o más son elegibles para recibir GIVbacks. ¡Impulsa este proyecto para aumentar su porcentaje de recompensas y su visibilidad en la página de proyectos!", + "project.givback_toast.description.verified_public_not_eligible": "{stakeLock} tus GIV tokens para obtener GIVpower. ¡Impulsa este proyecto para hacerlo más visible en la página de proyectos! Ten en cuenta que aunque este proyecto es elegible para ser impulsado con GIVpower, no generará GIVbacks para sus donantes.", + "project.givback_toast.title.non_verified_owner": "¿Tu proyecto está creando o apoyando bienes públicos?", "project.givback_toast.title.non_verified_owner_cancelled": "Estado Cancelado", "project.givback_toast.title.non_verified_owner_deactive": "Modo Desactivado", "project.givback_toast.title.non_verified_owner_draft": "¡Publica tu proyecto hoy!", @@ -1657,11 +1677,10 @@ "project.givback_toast.title.non_verified_owner_rejected": "No pudimos aprobar tu proyecto como elegible para GIVbacks", "project.givback_toast.title.non_verified_owner_submitted": "Solicitud enviada", "project.givback_toast.title.non_verified_public": "¿Por qué no GIVbacks?", - "project.givback_toast.title.verified_owner_1": "Los donantes reciben recompensas de hasta ", - "project.givback_toast.title.verified_owner_2": " del valor de la donación.", - "project.givback_toast.title.verified_owner_not_eligible": "Tu proyecto ha sido avalado", "project.givback_toast.title.verified_public_1": "¡Recibe recompensas de hasta ", - "project.givback_toast.title.verified_public_2": " del valor de tu donación!", + "project.givback_toast.title.verified_owner": "¡Las donaciones de ${value} o más califican para GIVbacks con hasta un {percent}%!", + "project.givback_toast.title.verified_owner_not_eligible": "Tu proyecto ha sido avalado", + "project.givback_toast.title.verified_public_2": " del valor de tu donación!", "project.givback_toast.title.verified_public_not_eligible": "Boostea este proyecto con GIVpower!", "projects_all": "Todos los proyectos", "projects_all_desc": "APOYE PROYECTOS GLOBALES EN BIENES PÚBLICOS, SOSTENIBILIDAD Y REGENERACIÓN CON CRIPTODONACIONES", diff --git a/lang/t_ca.json b/lang/t_ca.json index 035a6ceb9a..d2a5d33f70 100644 --- a/lang/t_ca.json +++ b/lang/t_ca.json @@ -142,7 +142,6 @@ "other": "Altres", "other_desc": " ", "page.donate.matching_toast.bottom_valid": "Els fons de finançament es destinaran al projecte seleccionat després que acabi la ronda. Dona a més projectes per rebre més finançament!", - "page.donate.matching_toast.upper_valid": "Coincidència estimada", "page.donate.passport_toast.description.eligible": "La teva donació és elegible per ser coincidida! Després de la", "page.donate.passport_toast.description.eligible_2": ", totes les donacions seran revisades per a la protecció contra el frau i els fons de coincidència es enviaran als projectes. Estigueu atents a les notificacions :)", "page.donate.passport_toast.description.non_eligible": "Fes que la teva donació coincideixi amb el finançament quadràtic!\nAugmenta la teva puntuació de Passaport Gitcoin abans", @@ -153,12 +152,10 @@ "project.givback_toast.description.non_verified_owner": "Pots demostrar que el teu projecte està proporcionant un bé públic? La verificació et dóna accés a una gran quantitat de beneficis com recompenses per a donants, major visibilitat i formes addicionals d'obtenir fons!", "project.givback_toast.description.non_verified_public": "Actualment, els GIVbacks només es concedeixen per donacions fetes a projectes verificats. La teva contribució encara és important, encara que no generi GIVbacks!", "project.givback_toast.description.verified_owner": "Impulsa el teu projecte per augmentar el seu percentatge de recompenses i fer-lo més visible a la pàgina de projectes!", - "project.givback_toast.description.verified_owner.note": "Com a propietari d'aquest projecte, no obtindràs GIV per donar-hi.", "project.givback_toast.description.verified_public": "Els donants de projectes verificats són recompensats amb GIV. Impulsa aquest projecte per augmentar el seu percentatge de recompenses i fer-lo més visible a la pàgina de projectes!", "project.givback_toast.title.non_verified_owner": "Porta el teu projecte al següent nivell amb la Verificació!", "project.givback_toast.title.non_verified_public": "Per què no hi ha GIVbacks?", "project.givback_toast.title.verified_owner_1": "Els donants són recompensats amb fins a ", - "project.givback_toast.title.verified_owner_2": " del valor de la donació!", "project.givback_toast.title.verified_public_1": "Obtén recompenses amb fins a ", "project.givback_toast.title.verified_public_2": " del valor de la teva donació!", "refi": "Refi", diff --git a/lang/t_es.json b/lang/t_es.json index ed8b276ea4..458545900a 100644 --- a/lang/t_es.json +++ b/lang/t_es.json @@ -108,7 +108,6 @@ "label.you_can_view_them_on_a_blockchain_explorer_here": "Puedes verlas en un explorador de blockchain aquí:", "other_desc": " ", "page.donate.matching_toast.bottom_valid": "Los fondos de emparejamiento se enviarán al proyecto seleccionado después de que termine la ronda. ¡Dona a más proyectos para recibir un mayor emparejamiento!", - "page.donate.matching_toast.upper_valid": "Igualación estimada", "page.donate.passport_toast.description.eligible": "¡Tu donación es elegible para ser igualada! Después de la", "page.donate.passport_toast.description.eligible_2": ", todas las donaciones serán revisadas para la protección contra fraudes y los fondos de igualación serán enviados a los proyectos. Mantente atento a las notificaciones :)", "page.donate.passport_toast.description.non_eligible": "¡Haz que tu donación sea igualada con financiación cuadrática!\nAumenta tu puntuación de Pasaporte Gitcoin antes", @@ -119,12 +118,10 @@ "project.givback_toast.description.non_verified_owner": "¿Puedes demostrar que tu proyecto está proporcionando un bien público? ¡La verificación te da acceso a una gran cantidad de beneficios como recompensas para los donantes, mayor visibilidad y formas adicionales de recaudar fondos!", "project.givback_toast.description.non_verified_public": "Los GIVbacks se otorgan actualmente solo por donaciones realizadas a proyectos verificados. ¡Tu contribución sigue siendo importante, incluso si no genera GIVbacks!", "project.givback_toast.description.verified_owner": "¡Impulsa tu proyecto para aumentar su porcentaje de recompensas y hacerlo más visible en la página de proyectos!", - "project.givback_toast.description.verified_owner.note": "Como propietario de este proyecto, no obtendrás GIV por donar a él.", "project.givback_toast.description.verified_public": "Los donantes a proyectos verificados son recompensados con GIV. ¡Impulsa este proyecto para aumentar su porcentaje de recompensas y hacerlo más visible en la página de proyectos!", "project.givback_toast.title.non_verified_owner": "¡Lleva tu proyecto al siguiente nivel con la Verificación!", "project.givback_toast.title.non_verified_public": "¿Por qué no hay GIVbacks?", "project.givback_toast.title.verified_owner_1": "Los donantes son recompensados con hasta ", - "project.givback_toast.title.verified_owner_2": " del valor de la donación!", "project.givback_toast.title.verified_public_1": "Obtén recompensas de hasta ", "project.givback_toast.title.verified_public_2": " del valor de tu donación!", "refi": "Refi", diff --git a/next.config.js b/next.config.js index 8934ee9c51..e3b9624895 100644 --- a/next.config.js +++ b/next.config.js @@ -7,10 +7,8 @@ const { withSentryConfig } = require('@sentry/nextjs'); const withBundleAnalyzer = require('@next/bundle-analyzer')({ enabled: process.env.ANALYZE === 'true', }); -var pjson = require('./package.json'); -const generateRobotsTxt = require('./scripts/generate-robots-txt'); -const isProduction = process.env.NEXT_PUBLIC_ENV === 'production'; +const generateRobotsTxt = require('./scripts/generate-robots-txt'); const defaultLocale = 'en'; const locales = ['ca', 'en', 'es']; @@ -61,6 +59,7 @@ const moduleExports = withBundleAnalyzer({ }, { protocol: 'https', port: '', hostname: 'ipfs.io' }, { protocol: 'https', port: '', hostname: '*.amazonaws.com' }, + { protocol: 'https', port: '', hostname: 'giveth.io' }, ], }, compiler: { diff --git a/package.json b/package.json index eea62b6720..1d85dde9a0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "givethdapp", - "version": "2.30.0", + "version": "2.32.1", "private": true, "scripts": { "build": "next build", diff --git a/pages/landings/ethdenver.tsx b/pages/landings/ethdenver.tsx index fd10a3eaf1..b8b40d5581 100644 --- a/pages/landings/ethdenver.tsx +++ b/pages/landings/ethdenver.tsx @@ -2,8 +2,6 @@ import Head from 'next/head'; import { GetStaticProps } from 'next'; import { FC } from 'react'; import EthDenverView from '@/components/views/landings/EthDenver'; -import { FETCH_CAMPAIGN_BY_SLUG } from '@/apollo/gql/gqlCampaign'; -import { client } from '@/apollo/apolloClient'; import { ICampaign } from '@/apollo/types/types'; export interface IEthDenverProps { @@ -23,18 +21,22 @@ const EthDenverRoute: FC = ({ campaign }) => { export const getStaticProps: GetStaticProps = async () => { try { - const { data } = await client.query({ - query: FETCH_CAMPAIGN_BY_SLUG, - variables: { - slug: 'ethDenver', - }, - fetchPolicy: 'no-cache', - }); + //The campaign in not active + // const { data } = await client.query({ + // query: FETCH_CAMPAIGN_BY_SLUG, + // variables: { + // slug: 'ethDenver', + // }, + // fetchPolicy: 'no-cache', + // }); + // return { + // props: { + // campaign: data.findCampaignBySlug, + // }, + // revalidate: 600, + // }; return { - props: { - campaign: data.findCampaignBySlug, - }, - revalidate: 600, + props: {}, }; } catch (error) { return { diff --git a/pages/test2.tsx b/pages/test2.tsx index a7ec5e24fe..c9256c9843 100644 --- a/pages/test2.tsx +++ b/pages/test2.tsx @@ -31,8 +31,6 @@ const YourApp = () => { })), }); - console.log('subgraphValues', subgraphValues); - // Solana wallet hooks const { publicKey, diff --git a/public/images/banners/qf-round/giv-palooza.svg b/public/images/banners/qf-round/giv-palooza.svg index 5da6cdab05..360140de1e 100644 --- a/public/images/banners/qf-round/giv-palooza.svg +++ b/public/images/banners/qf-round/giv-palooza.svg @@ -1,295 +1,295 @@ - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + - - - - - - - - + + + + + + + + - - + + - + - - + + - - + + - - + + - + - - + + - - + + - + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - - - - + + + + diff --git a/public/images/logo/stellar.svg b/public/images/logo/stellar.svg new file mode 100644 index 0000000000..36d82c0595 --- /dev/null +++ b/public/images/logo/stellar.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/public/images/tokens/XLM.svg b/public/images/tokens/XLM.svg index 2f9b9c8ae5..1f210ba74c 100644 --- a/public/images/tokens/XLM.svg +++ b/public/images/tokens/XLM.svg @@ -1,7 +1,4 @@ - - - + + + - \ No newline at end of file diff --git a/src/apollo/apolloClient.ts b/src/apollo/apolloClient.ts index a40a3ff0cb..6bf978265c 100644 --- a/src/apollo/apolloClient.ts +++ b/src/apollo/apolloClient.ts @@ -1,7 +1,6 @@ import { useMemo } from 'react'; import { ApolloClient, InMemoryCache, ApolloLink } from '@apollo/client'; import { RetryLink } from '@apollo/client/link/retry'; - import { setContext } from '@apollo/client/link/context'; import { onError } from '@apollo/client/link/error'; import gql from 'graphql-tag'; @@ -95,7 +94,7 @@ function createApolloClient() { const httpLink = createUploadLink({ uri: config.BACKEND_LINK, fetch: customFetch as any, - }) as unknown as ApolloLink; + }); const authLink = setContext((_, { headers }) => { let locale: string | null = !ssrMode @@ -149,9 +148,12 @@ function createApolloClient() { } }); + // Combine all links using ApolloLink.from to fix terminating link error + const link = ApolloLink.from([errorLink, authLink, retryLink, httpLink]); + return new ApolloClient({ ssrMode, - link: errorLink.concat(authLink.concat(httpLink.concat(retryLink))), + link: link, cache: new InMemoryCache({ addTypename: false, }), @@ -161,7 +163,6 @@ function createApolloClient() { }, query: { fetchPolicy: 'cache-first', - // nextFetchPolicy: 'cache-first', }, }, typeDefs: gql` diff --git a/src/components/GIVeconomyPages/GIVbacks.tsx b/src/components/GIVeconomyPages/GIVbacks.tsx index 3d9df06ddd..a92296b817 100644 --- a/src/components/GIVeconomyPages/GIVbacks.tsx +++ b/src/components/GIVeconomyPages/GIVbacks.tsx @@ -274,7 +274,7 @@ export const TabGIVbacksBottom = () => { {givbackAllocations && givbackAllocations.allocatedGivTokens ? `${givbackAllocations.allocatedGivTokens} GIV` - : '?'} + : 'TBD'} diff --git a/src/components/GIVeconomyPages/GIVpower.tsx b/src/components/GIVeconomyPages/GIVpower.tsx index d28e106e81..9d1720f2cc 100644 --- a/src/components/GIVeconomyPages/GIVpower.tsx +++ b/src/components/GIVeconomyPages/GIVpower.tsx @@ -1,7 +1,6 @@ import Image from 'next/image'; import { brandColors, - H3, H4, IconRocketInSpace32, QuoteText, @@ -22,9 +21,6 @@ import { GIVpowerTopContainer, Title, Subtitle, - LearnMoreButton, - HeadingSectionContainer, - HeadingTextContainer, FeaturesCardContainer, FeaturesCardHeading, FeaturesCardSubheading, @@ -62,7 +58,6 @@ import GivStake from '../../../public/images/giv_stake.svg'; import Routes from '@/lib/constants/Routes'; import config from '@/configuration'; import { formatWeiHelper } from '@/helpers/number'; -import links from '@/lib/constants/links'; import { getTotalGIVpower } from '@/helpers/givpower'; import { useGeneralWallet } from '@/providers/generalWalletProvider'; import { ChainType } from '@/types/config'; @@ -218,28 +213,6 @@ export function TabPowerBottom() { return ( <> -

- {formatMessage({ - id: 'label.boost_projects_with_givpower', - })} -

-
- - - - {formatMessage({ - id: 'label.use_your_givpower_to_boost_verified_projects', - })} - - - - {formatMessage({ id: 'label.how_does_givpower_work' })} @@ -342,6 +315,7 @@ export function TabPowerBottom() { {formatMessage({ id: 'label.for_givers' })} +
{/* Adding a line break here */} @@ -374,6 +348,7 @@ export function TabPowerBottom() { {formatMessage({ id: 'label.for_projects' })} +
{/* Adding a line break here */} {formatMessage({ diff --git a/src/components/GIVeconomyPages/GIVstream.tsx b/src/components/GIVeconomyPages/GIVstream.tsx index b775a7d4cd..7b20734b56 100644 --- a/src/components/GIVeconomyPages/GIVstream.tsx +++ b/src/components/GIVeconomyPages/GIVstream.tsx @@ -10,7 +10,6 @@ import { IconGIVStream, IconHelpFilled16, IconPraise24, - IconSpark, P, Container, Row, @@ -45,8 +44,6 @@ import { HistoryTitle, HistoryTitleRow, HistoryTooltip, - IncreaseSection, - IncreaseSectionTitle, NoData, PercentageRow, TxHash, @@ -66,7 +63,6 @@ import { ITokenAllocation } from '@/types/subgraph'; import { IconGIV } from '../Icons/GIV'; import { givEconomySupportedNetworks } from '@/lib/constants/constants'; import Pagination from '../Pagination'; -import GivEconomyProjectCards from '../cards/GivEconomyProjectCards'; import { SubgraphDataHelper } from '@/lib/subgraph/subgraphDataHelper'; export const TabGIVstreamTop = () => { @@ -291,15 +287,6 @@ export const TabGIVstreamBottom = () => { - - - - {formatMessage({ id: 'label.increase_your_givstream' })} - - - - - ); }; diff --git a/src/components/GIVeconomyPages/commons.tsx b/src/components/GIVeconomyPages/commons.tsx index 71e293bdca..b842f55d25 100644 --- a/src/components/GIVeconomyPages/commons.tsx +++ b/src/components/GIVeconomyPages/commons.tsx @@ -13,7 +13,7 @@ export const TopContainer = styled(Flex)` background-image: url('/images/backgrounds/givup.svg'); height: auto; ${mediaQueries.tablet} { - height: 370px; + height: 400px; } `; diff --git a/src/components/IconWithToolTip.tsx b/src/components/IconWithToolTip.tsx index d23c741dce..8c520a5671 100644 --- a/src/components/IconWithToolTip.tsx +++ b/src/components/IconWithToolTip.tsx @@ -1,11 +1,12 @@ import styled from 'styled-components'; -import { useEffect, useRef, useState } from 'react'; +import { CSSProperties, useEffect, useRef, useState } from 'react'; import { ITooltipDirection, Tooltip } from './Tooltip'; import type { FC, ReactNode } from 'react'; interface IIconWithTooltipProps extends ITooltipDirection { icon: ReactNode; children: ReactNode; + style?: CSSProperties; delay?: boolean; } @@ -15,6 +16,7 @@ export const IconWithTooltip: FC = ({ align = 'center', children, delay = false, + style, }) => { const [show, setShow] = useState(false); const elRef = useRef(null); @@ -59,6 +61,7 @@ export const IconWithTooltip: FC = ({ e.stopPropagation(); // make tooltip content clickable without affecting parent }} ref={elRef} + style={style} > {icon} {show && ( diff --git a/src/components/RewardCard.tsx b/src/components/RewardCard.tsx index 1d81596c37..45f7a228af 100644 --- a/src/components/RewardCard.tsx +++ b/src/components/RewardCard.tsx @@ -21,7 +21,7 @@ import useGIVTokenDistroHelper from '@/hooks/useGIVTokenDistroHelper'; import NetworkLogo from './NetworkLogo'; import { ScaleRate, ScaleRateBig } from '@/lib/constants/constants'; import { getChainName } from '@/lib/network'; -import { INetworkIdWithChain } from './views/donate/common.types'; +import { INetworkIdWithChain } from './views/donate/common/common.types'; import { ChainType } from '@/types/config'; import { EVMWrongNetworkSwitchModal } from './modals/WrongNetworkInnerModal'; import { useFetchGIVPrice } from '@/hooks/useGivPrice'; diff --git a/src/components/ToggleSwitch.tsx b/src/components/ToggleSwitch.tsx index efa00f7775..c58aa30b65 100644 --- a/src/components/ToggleSwitch.tsx +++ b/src/components/ToggleSwitch.tsx @@ -1,6 +1,15 @@ import styled from 'styled-components'; import { brandColors, neutralColors, P, Flex } from '@giveth/ui-design-system'; -import { FC } from 'react'; +import { CSSProperties, FC } from 'react'; + +export enum EToggleSwitchSizes { + SMALL = 'small', + MEDIUM = 'medium', +} +export enum EToggleSwitchThemes { + DEFAULT = 'default', + PURPLE_GRAY = 'purple-gray', +} interface IToggleButton { isOn: boolean; @@ -8,6 +17,9 @@ interface IToggleButton { label: string; disabled?: boolean; className?: string; + size?: EToggleSwitchSizes; + theme?: EToggleSwitchThemes; + style?: CSSProperties; } const ToggleSwitch: FC = ({ @@ -16,6 +28,9 @@ const ToggleSwitch: FC = ({ label, disabled, className, + size, + theme, + style, }) => { const handleClick = () => { toggleOnOff(!isOn); @@ -25,12 +40,15 @@ const ToggleSwitch: FC = ({ onClick={handleClick} $disabled={disabled} className={className} + style={style} > {}} /> - - + + - {label} + + {label} + ); }; @@ -41,40 +59,72 @@ const InputStyled = styled.input` height: 0; `; -const Bullet = styled.div<{ $isOn: boolean }>` +const Bullet = styled.div<{ + $isOn: boolean; + size?: EToggleSwitchSizes; + theme?: EToggleSwitchThemes; +}>` position: absolute; border-radius: 50%; - width: 14px; - height: 14px; - background-color: ${brandColors.pinky[200]}; + width: ${props => + props.size === EToggleSwitchSizes.SMALL ? '10px' : '14px'}; + height: ${props => + props.size === EToggleSwitchSizes.SMALL ? '10px' : '14px'}; + background-color: ${props => + props.theme === EToggleSwitchThemes.PURPLE_GRAY + ? 'white' + : brandColors.pinky[200]}; border: 3px solid white; - left: ${props => (props.$isOn ? '15px' : '1px')}; + left: ${({ $isOn, size }) => + $isOn + ? size === EToggleSwitchSizes.SMALL + ? '12px' + : '15px' + : size === EToggleSwitchSizes.SMALL + ? '2px' + : '1px'}; transition: left 0.2s ease-in-out; - top: 1px; + top: ${props => (props.size === EToggleSwitchSizes.SMALL ? '2px' : '1px')}; `; -const Switch = styled.span<{ $isOn: boolean }>` +const Switch = styled.span<{ + $isOn: boolean; + size?: EToggleSwitchSizes; + theme?: EToggleSwitchThemes; +}>` position: relative; - width: 30px; - height: 16px; + width: ${props => + props.size === EToggleSwitchSizes.SMALL ? '24px' : '30px'}; + height: ${props => + props.size === EToggleSwitchSizes.SMALL ? '14px' : '16px'}; flex-shrink: 0; padding-left: 1px; padding-right: 1px; border-radius: 50px; cursor: pointer; background-color: ${props => - props.$isOn ? brandColors.pinky[500] : neutralColors.gray[700]}; + props.$isOn + ? props.theme === EToggleSwitchThemes.PURPLE_GRAY + ? brandColors.giv[500] + : brandColors.pinky[500] + : props.theme === EToggleSwitchThemes.PURPLE_GRAY + ? neutralColors.gray[300] + : neutralColors.gray[700]}; transition: background-color 0.3s ease-in-out; `; -const Caption = styled(P)` +const Caption = styled(P)<{ size?: EToggleSwitchSizes }>` color: ${neutralColors.gray[800]}; + font-weight: 500; + font-size: ${props => + props.size === EToggleSwitchSizes.SMALL ? '14px !important' : '16px'}; `; const Container = styled(Flex)<{ $disabled?: boolean }>` + pointer-events: ${props => (props.$disabled ? 'none' : 'auto')}; gap: 8px; align-items: center; - cursor: pointer; + cursor: ${props => (props.$disabled ? 'default' : 'pointer')}; opacity: ${props => (props.$disabled ? 0.3 : 1)}; `; diff --git a/src/components/cards/MintCard.tsx b/src/components/cards/MintCard.tsx index 52409ebb5b..cc91527a38 100644 --- a/src/components/cards/MintCard.tsx +++ b/src/components/cards/MintCard.tsx @@ -18,13 +18,15 @@ import { readContracts, readContract } from '@wagmi/core'; import { MintModal } from '../modals/Mint/MintModal'; import { formatWeiHelper } from '@/helpers/number'; import config from '@/configuration'; -import { abi as PFP_ABI } from '@/artifacts/pfpGiver.json'; +import PFP_ARTIFACTS from '@/artifacts/pfpGiver.json'; import { InsufficientFundModal } from '../modals/InsufficientFund'; import { usePFPMintData } from '@/context/pfpmint.context'; import { useGeneralWallet } from '@/providers/generalWalletProvider'; import { wagmiConfig } from '@/wagmiConfigs'; import { getReadContractResult } from '@/lib/contracts'; + const MIN_NFT_QTY = 1; +const PFP_ABI = PFP_ARTIFACTS.abi as Abi; interface IpfpContractData { price: bigint; @@ -71,7 +73,7 @@ export const MintCard = () => { const baseParams = { address: config.MAINNET_CONFIG.PFP_CONTRACT_ADDRESS, chainId: config.MAINNET_NETWORK_NUMBER, - abi: PFP_ABI as Abi, + abi: PFP_ABI, } as const; const result = await readContracts(wagmiConfig, { contracts: [ @@ -121,7 +123,7 @@ export const MintCard = () => { const _balanceOf = await readContract(wagmiConfig, { address: config.MAINNET_CONFIG.PFP_CONTRACT_ADDRESS, chainId: config.MAINNET_NETWORK_NUMBER, - abi: PFP_ABI as Abi, + abi: PFP_ABI, functionName: 'balanceOf', args: [walletAddress], }); diff --git a/src/components/input/BaseInput.tsx b/src/components/input/BaseInput.tsx index a6a92b4192..fdb5fb64b0 100644 --- a/src/components/input/BaseInput.tsx +++ b/src/components/input/BaseInput.tsx @@ -60,6 +60,7 @@ export const BaseInput = memo( BaseInput.displayName = 'BaseInput'; const Input = styled.input` + background-color: inherit; border: 0; flex: 1; font-size: 18px; diff --git a/src/components/modals/DonateWrongNetwork.tsx b/src/components/modals/DonateWrongNetwork.tsx index d06945db60..bd6ce67588 100644 --- a/src/components/modals/DonateWrongNetwork.tsx +++ b/src/components/modals/DonateWrongNetwork.tsx @@ -21,7 +21,7 @@ import { mediaQueries } from '@/lib/constants/constants'; import { Modal } from './Modal'; import { IModal } from '@/types/common'; import { useModalAnimation } from '@/hooks/useModalAnimation'; -import { INetworkIdWithChain } from '@/components/views/donate/common.types'; +import { INetworkIdWithChain } from '@/components/views/donate/common/common.types'; import config from '@/configuration'; import NetworkLogo from '../NetworkLogo'; import { NetworkItem, SelectedNetwork } from './SwitchNetwork'; diff --git a/src/components/modals/Mint/MintModal.tsx b/src/components/modals/Mint/MintModal.tsx index 52dd4131eb..e86ec68bf2 100644 --- a/src/components/modals/Mint/MintModal.tsx +++ b/src/components/modals/Mint/MintModal.tsx @@ -10,6 +10,7 @@ import { } from '@giveth/ui-design-system'; import { useAccount } from 'wagmi'; import { writeContract } from '@wagmi/core'; +import { Abi } from 'viem'; import { IModal } from '@/types/common'; import { Modal } from '../Modal'; import { useModalAnimation } from '@/hooks/useModalAnimation'; @@ -18,16 +19,19 @@ import { formatWeiHelper } from '@/helpers/number'; import { waitForTransaction } from '@/lib/transaction'; import { approveERC20tokenTransfer } from '@/lib/stakingPool'; import config from '@/configuration'; -import { abi as PFP_ABI } from '@/artifacts/pfpGiver.json'; +import PFP_ARTIFACTS from '@/artifacts/pfpGiver.json'; + import { EPFPMinSteps, usePFPMintData } from '@/context/pfpmint.context'; import { MintSteps } from './MintSteps'; import { wagmiConfig } from '@/wagmiConfigs'; + export enum MintStep { APPROVE, APPROVING, MINT, MINTING, } +const PFP_ABI = PFP_ARTIFACTS.abi as Abi; interface IMintModalProps extends IModal { qty: number; diff --git a/src/components/modals/SwitchNetwork.tsx b/src/components/modals/SwitchNetwork.tsx index 618ece34e5..7130d0d2dc 100644 --- a/src/components/modals/SwitchNetwork.tsx +++ b/src/components/modals/SwitchNetwork.tsx @@ -19,7 +19,7 @@ import { useAppSelector } from '@/features/hooks'; import config from '@/configuration'; import { ETheme } from '@/features/general/general.slice'; import { getChainName } from '@/lib/network'; -import { INetworkIdWithChain } from '../views/donate/common.types'; +import { INetworkIdWithChain } from '../views/donate/common/common.types'; import { useGeneralWallet } from '@/providers/generalWalletProvider'; import { ChainType } from '@/types/config'; @@ -42,8 +42,12 @@ const SwitchNetwork: FC = ({ const { switchChain } = useSwitchChain(); const { formatMessage } = useIntl(); - const { walletChainType, handleSingOutAndSignInWithEVM, chain } = - useGeneralWallet(); + const { + walletChainType, + handleSingOutAndSignInWithEVM, + handleSignOutAndSignInWithSolana, + chain, + } = useGeneralWallet(); const chainId = (chain as Chain)?.id; const theme = useAppSelector(state => state.general.theme); @@ -71,7 +75,14 @@ const SwitchNetwork: FC = ({ if (walletChainType === ChainType.SOLANA) { handleSingOutAndSignInWithEVM(); } - switchChain?.({ chainId: networkId }); + if ( + walletChainType === ChainType.EVM && + chainType === ChainType.SOLANA + ) { + handleSignOutAndSignInWithSolana(); + } else { + switchChain?.({ chainId: networkId }); + } closeModal(); }} $isSelected={networkId === chainId} diff --git a/src/components/modals/WrongNetworkInnerModal.tsx b/src/components/modals/WrongNetworkInnerModal.tsx index 6f8d78cc50..19908c94a6 100644 --- a/src/components/modals/WrongNetworkInnerModal.tsx +++ b/src/components/modals/WrongNetworkInnerModal.tsx @@ -7,7 +7,7 @@ import { mediaQueries } from '@/lib/constants/constants'; import { jointItems } from '@/helpers/text'; import SwitchNetwork from './SwitchNetwork'; import { getChainName } from '@/lib/network'; -import { INetworkIdWithChain } from '../views/donate/common.types'; +import { INetworkIdWithChain } from '../views/donate/common/common.types'; import { useGeneralWallet } from '@/providers/generalWalletProvider'; import { ChainType } from '@/types/config'; diff --git a/src/components/views/donate/DonateIndex.tsx b/src/components/views/donate/DonateIndex.tsx index e3a50ecf88..6ed2443f4b 100644 --- a/src/components/views/donate/DonateIndex.tsx +++ b/src/components/views/donate/DonateIndex.tsx @@ -11,6 +11,7 @@ import { Flex, B, Button, + H4, } from '@giveth/ui-design-system'; import { useIntl } from 'react-intl'; import { useRouter } from 'next/router'; @@ -21,7 +22,6 @@ import useDetectDevice from '@/hooks/useDetectDevice'; import { useIsSafeEnvironment } from '@/hooks/useSafeAutoConnect'; import { useDonateData } from '@/context/donate.context'; import { EContentType } from '@/lib/constants/shareContent'; -import { PassportBanner } from '@/components/PassportBanner'; import { useAlreadyDonatedToProject } from '@/hooks/useAlreadyDonatedToProject'; import { Shadow } from '@/components/styled-components/Shadow'; import { useAppDispatch, useAppSelector } from '@/features/hooks'; @@ -33,8 +33,7 @@ import QFSection from '../project/projectActionCard/QFSection'; import ProjectCardImage from '@/components/project-card/ProjectCardImage'; import { useGeneralWallet } from '@/providers/generalWalletProvider'; import { DonatePageProjectDescription } from './DonatePageProjectDescription'; -import { getActiveRound } from '@/helpers/qf'; -import QRDonationDetails from './OnTime/SelectTokenModal/QRCodeDonation/QRDonationDetails'; +import QRDonationDetails from '@/components/views/donate/OneTime/SelectTokenModal/QRCodeDonation/QRDonationDetails'; import InlineToast, { EToastType } from '@/components/toasts/InlineToast'; import { client } from '@/apollo/apolloClient'; import { FETCH_DONATION_BY_ID } from '@/apollo/gql/gqlDonations'; @@ -46,6 +45,9 @@ import EndaomentProjectsInfo from '@/components/views/project/EndaomentProjectsI import { IDraftDonation } from '@/apollo/types/gqlTypes'; import StorageLabel from '@/lib/localStorage'; import DonationByProjectOwner from '@/components/modals/DonationByProjectOwner'; +import { PassportBanner } from '@/components/PassportBanner'; +import QFEligibleNetworks from '@/components/views/donate/QFEligibleNetworks'; +import { GIVBACKS_DONATION_QUALIFICATION_VALUE_USD } from '@/lib/constants/constants'; const DonateIndex: FC = () => { const { formatMessage } = useIntl(); @@ -60,6 +62,7 @@ const DonateIndex: FC = () => { setQRDonationStatus, setDraftDonationData, setPendingDonationExists, + activeStartedRound, startTimer, } = useDonateData(); const { renewExpirationDate, retrieveDraftDonation } = @@ -80,6 +83,12 @@ const DonateIndex: FC = () => { ); const [stopTimer, setStopTimer] = React.useState void)>(); + const isQRDonation = router.query.chain === ChainType.STELLAR.toLowerCase(); + const isStellarIncludedInQF = + activeStartedRound?.eligibleNetworks?.includes( + config.STELLAR_NETWORK_NUMBER, + ); + useEffect(() => { dispatch(setShowHeader(false)); return () => { @@ -112,7 +121,11 @@ const DonateIndex: FC = () => { getDonationById; if (!transactionId) return; - + const includeInQF = + activeStartedRound && + !!getDonationById.valueUsd && + getDonationById.valueUsd >= + (activeStartedRound?.minimumValidUsdValue || 0); setSuccessDonation({ txHash: [ { @@ -120,11 +133,14 @@ const DonateIndex: FC = () => { chainType: ChainType.STELLAR, }, ], + excludeFromQF: !includeInQF, givBackEligible: isTokenEligibleForGivback && project.isGivbackEligible && isSignedIn && - isEnabled, + isEnabled && + getDonationById.amount >= + GIVBACKS_DONATION_QUALIFICATION_VALUE_USD, chainId: config.STELLAR_NETWORK_NUMBER, }); } @@ -133,10 +149,12 @@ const DonateIndex: FC = () => { }, [qrDonationStatus]); const isRecurringTab = router.query.tab?.toString() === ETabs.RECURRING; - const { activeStartedRound } = getActiveRound(project.qfRounds); const isOnEligibleNetworks = chainId && activeStartedRound?.eligibleNetworks?.includes(chainId); const isFailedOperation = ['expired', 'failed'].includes(qrDonationStatus); + const showAlreadyDonatedWrapper = + alreadyDonated && + (isQRDonation ? isStellarIncludedInQF : isOnEligibleNetworks); const updateQRCode = async () => { if (!draftDonationData?.id) return; @@ -213,107 +231,126 @@ const DonateIndex: FC = () => { return successDonation ? ( <> - - - + + + ) : ( <> - - {showDonationByProjectOwner && ( - - )} - {alreadyDonated && ( - - - - {formatMessage({ - id: 'component.already_donated.incorrect_estimate', - })} - - - )} - {!isSafeEnv && hasActiveQFRound && !isOnSolana && ( - - )} - - - - + {!isSafeEnv && + hasActiveQFRound && + !isOnSolana && + (!isQRDonation || + (isQRDonation && isStellarIncludedInQF)) && ( + + )} + + {showDonationByProjectOwner && ( + - - - - {showQRCode ? ( - - ) : ( - <> - - - + + + {formatMessage({ + id: 'component.already_donated.incorrect_estimate', + })} + + + )} + + + + + + + + {showQRCode ? ( + + ) : ( + <> + - - {!isMobile ? ( - (!isRecurringTab && hasActiveQFRound) || - (isRecurringTab && - isOnEligibleNetworks) ? ( - - ) : ( - + )} + + - ) - ) : null} - + + + {!isMobile ? ( + isRecurringTab && + isOnEligibleNetworks ? ( + + ) : ( + + ) + ) : null} + + )} + + {isFailedOperation && ( + + + {formatMessage({ + id: 'label.need_a_new_qr_code', + })} + + + + )} - - {isFailedOperation && ( - - - {formatMessage({ - id: 'label.need_a_new_qr_code', - })} - - - - - )} - - - {!isMobile && ( - - )} - + + + {!isMobile && ( + + )} + + ); }; +const Wrapper = styled.div` + margin-top: 91px; +`; + const AlreadyDonatedWrapper = styled(Flex)` margin-bottom: 16px; padding: 12px 16px; @@ -325,13 +362,20 @@ const AlreadyDonatedWrapper = styled(Flex)` align-items: center; `; -const DonateContainer = styled(Container)` +const DonateSuccessContainer = styled(Container)` text-align: center; padding-top: 110px; padding-bottom: 64px; position: relative; `; +const DonateContainer = styled(Container)` + text-align: center; + padding-top: 10px; + padding-bottom: 64px; + position: relative; +`; + const InfoWrapper = styled.div` background-color: ${neutralColors.gray[100]}; padding: 24px; @@ -362,4 +406,41 @@ const ButtonStyled = styled(Button)` text-transform: capitalize; `; +const ProjectImage = styled.img` + border-radius: 16px; + width: 100%; + object-fit: cover; // Ensures the image covers the entire container + height: 380px; + position: relative; +`; + +const GradientOverlay = styled.div` + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 380px; + background: linear-gradient( + to top, + rgba(1, 1, 27, 0.6), + transparent + ); /* Dark navy to transparent gradient */ + border-radius: 16px; +`; + +const Title = styled(H4)` + position: absolute; + bottom: 40px; + left: 40px; + color: #ffffff; + font-weight: bold; + text-align: left; + z-index: 1; + max-width: 90%; // Set max-width to a suitable percentage value based on your preference + white-space: pre-wrap; // Allows the text to wrap to the next line + > div:first-child { + margin-bottom: 4px; + } +`; + export default DonateIndex; diff --git a/src/components/views/donate/DonatePageProjectDescription.tsx b/src/components/views/donate/DonatePageProjectDescription.tsx index 25decd8889..33a17e0d32 100644 --- a/src/components/views/donate/DonatePageProjectDescription.tsx +++ b/src/components/views/donate/DonatePageProjectDescription.tsx @@ -8,11 +8,14 @@ import { mediaQueries, Flex, H5, + semanticColors, + H4, } from '@giveth/ui-design-system'; import { useIntl } from 'react-intl'; import styled from 'styled-components'; import { type FC } from 'react'; import Link from 'next/link'; +import { useRouter } from 'next/router'; import { formatDonation } from '@/helpers/number'; import { IProject } from '@/apollo/types/types'; import { VerifiedBadge } from '@/components/badges/VerifiedBadge'; @@ -20,6 +23,9 @@ import { slugToProjectView } from '@/lib/routeCreators'; import { ProjectCardUserName } from '@/components/project-card/ProjectCardUserName'; import { ORGANIZATION } from '@/lib/constants/organizations'; import { useDonateData } from '@/context/donate.context'; +import { ChainType } from '@/types/config'; +import config from '@/configuration'; +import { calculateTotalEstimatedMatching, getActiveRound } from '@/helpers/qf'; import { GivBackBadge } from '@/components/badges/GivBackBadge'; interface IDonatePageProjectDescriptionProps { @@ -31,15 +37,22 @@ export const DonatePageProjectDescription: FC< IDonatePageProjectDescriptionProps > = ({ projectData, showRaised = true }) => { const { formatMessage, locale } = useIntl(); + const router = useRouter(); const { totalDonations, + sumDonationValueUsdForActiveQfRound, + countUniqueDonorsForActiveQfRound, slug, title, descriptionSummary, adminUser, organization, + estimatedMatching, } = projectData || {}; + const { allProjectsSum, matchingPool, projectDonationsSqrtRootSum } = + estimatedMatching || {}; + const isQRDonation = router.query.chain === ChainType.STELLAR.toLowerCase(); const orgLabel = organization?.label; const isForeignOrg = orgLabel !== ORGANIZATION.trace && orgLabel !== ORGANIZATION.giveth; @@ -47,6 +60,21 @@ export const DonatePageProjectDescription: FC< const projectLink = slugToProjectView(slug!); const { project } = useDonateData(); + const { activeStartedRound, activeQFRound } = getActiveRound( + project.qfRounds, + ); + + const isStellarIncludedInQF = + activeStartedRound?.eligibleNetworks?.includes( + config.STELLAR_NETWORK_NUMBER, + ); + + const { + allocatedFundUSDPreferred, + allocatedFundUSD, + allocatedTokenSymbol, + } = activeQFRound || {}; + return ( {projectData?.isGivbackEligible && ( @@ -69,42 +97,120 @@ export const DonatePageProjectDescription: FC< isForeignOrg={isForeignOrg} sidePadding='0' /> - {showRaised && ( -

- {formatMessage({ id: 'label.raised' })}:{' '} - {formatDonation(totalDonations || 0, '$', locale)} -

- )} - {descriptionSummary} - {project?.organization?.label === ORGANIZATION.endaoment ? null : ( - - - {formatMessage({ - id: 'component.donation_section.100_to_the_project', - })} - - -

- {formatMessage({ - id: 'component.donation_section.desc', - })} -

- - - + {isQRDonation && isStellarIncludedInQF && showRaised ? ( + <> + {sumDonationValueUsdForActiveQfRound || 0 ? ( + <> + + + {formatMessage({ + id: 'label.amount_raised_in_this_round', + })} + + + + {formatDonation( + sumDonationValueUsdForActiveQfRound || 0, + '$', + locale, + )} + + +
+ + {formatMessage({ + id: 'label.raised_from', + })}{' '} + + +   + {countUniqueDonorsForActiveQfRound || 0} +   + + + {formatMessage( + { + id: 'label.contributors', + }, + { + count: countUniqueDonorsForActiveQfRound, + }, + )} + +
+ + +  + {formatDonation( + calculateTotalEstimatedMatching( + projectDonationsSqrtRootSum, + allProjectsSum, + allocatedFundUSDPreferred + ? allocatedFundUSD + : matchingPool, + activeStartedRound?.maximumReward, + ), + allocatedFundUSDPreferred ? '$' : '', + locale, + true, + )} + {allocatedFundUSDPreferred + ? '' + : ` ${allocatedTokenSymbol}`} + + + ) : ( + + {formatMessage({ - id: 'component.donation_section.learn_zero_fee', + id: 'label.donate_first_lead_the_way', })} -
- -
-
-
+ + + )} + + ) : ( + <> + {showRaised && ( +

+ {formatMessage({ id: 'label.raised' })}:{' '} + {formatDonation(totalDonations || 0, '$', locale)} +

+ )} + + {descriptionSummary} + + {project?.organization?.label === + ORGANIZATION.endaoment ? null : ( + + + {formatMessage({ + id: 'component.donation_section.100_to_the_project', + })} + + +

+ {formatMessage({ + id: 'component.donation_section.desc', + })} +

+ + + + {formatMessage({ + id: 'component.donation_section.learn_zero_fee', + })} + + + + +
+ )} + )}
); @@ -146,3 +252,36 @@ const LearnLink = styled(Flex)` color: ${brandColors.pinky[700]}; } `; +const AmountRaisedText = styled(Subline)` + color: ${neutralColors.gray[700]}; + background-color: ${neutralColors.gray[300]}; + padding: 2px 0; + width: fit-content; + > span { + font-weight: 500; + } +`; + +const PriceText = styled(H5)` + display: inline; + color: ${neutralColors.gray[900]}; + font-weight: 700; +`; + +const LightSubline = styled(Subline)` + display: inline-block; + color: ${neutralColors.gray[700]}; +`; + +const EstimatedMatchingPrice = styled(H5)` + color: ${semanticColors.jade[500]}; +`; + +const DonateInfo = styled.div` + height: 130px; +`; + +const NoFund = styled(H4)` + color: ${neutralColors.gray[800]}; + margin-top: 16px; +`; diff --git a/src/components/views/donate/DonateToGiveth.tsx b/src/components/views/donate/DonateToGiveth.tsx index c055c8b132..3383d8669b 100644 --- a/src/components/views/donate/DonateToGiveth.tsx +++ b/src/components/views/donate/DonateToGiveth.tsx @@ -1,12 +1,11 @@ import { brandColors, - Caption, + Flex, GLink, IconHelpFilled16, mediaQueries, neutralColors, Subline, - Flex, } from '@giveth/ui-design-system'; import styled from 'styled-components'; import { ChangeEvent, FC } from 'react'; @@ -14,26 +13,30 @@ import { useIntl } from 'react-intl'; import { IconWithTooltip } from '@/components/IconWithToolTip'; import Input, { InputSize } from '@/components/Input'; import { InputSuffix } from '@/components/styled-components/Input'; -import CheckBox from '@/components/Checkbox'; +import ToggleSwitch, { + EToggleSwitchSizes, + EToggleSwitchThemes, +} from '@/components/ToggleSwitch'; interface IDonateToGiveth { donationToGiveth: number; - givethDonationAmount?: number; setDonationToGiveth: (donationToGiveth: number) => void; title: string; + disabled?: boolean; } const givethDonationOptions = [5, 10, 15, 20]; const DonateToGiveth: FC = ({ donationToGiveth, - givethDonationAmount, setDonationToGiveth, title, + disabled, }) => { const { formatMessage } = useIntl(); const handleChange = (e: ChangeEvent) => { + if (disabled) return; const newPercentage = +e.target.value; if (isNaN(newPercentage) || newPercentage < 0 || newPercentage > 90) return; @@ -41,32 +44,44 @@ const DonateToGiveth: FC = ({ }; const handleCheckbox = (e: boolean) => { - setDonationToGiveth(e ? 0 : 5); + setDonationToGiveth(e ? 5 : 0); }; - // If givethDonationAmount props provided check if it's 0 and set donationToGiveth to 0 - // because we disabled percetange amount for minimal allowed main donation amount - if (givethDonationAmount !== undefined) { - donationToGiveth = givethDonationAmount === 0 ? 0 : donationToGiveth; - } - return ( - {title} - } direction='top'> + + } + direction='top' + > {formatMessage({ id: 'label.support_giveth_with' })} - + {givethDonationOptions.map(option => ( setDonationToGiveth(option)} + onClick={() => + !disabled && setDonationToGiveth(option) + } > {option}% @@ -81,15 +96,6 @@ const DonateToGiveth: FC = ({ } /> - ); }; @@ -101,16 +107,23 @@ const TooltipContainer = styled(Subline)` padding: 0 10px; `; -const UserInput = styled(Flex)` - margin-top: 16px; +const UserInput = styled(Flex)<{ disabled?: boolean }>` + margin-top: 12px; justify-content: space-between; gap: 10px; flex-wrap: wrap; + opacity: ${props => (props.disabled ? 0.4 : 1)}; `; const StyledInput = styled(Input)` - width: 90px; + width: 50px; flex: none; + margin-bottom: -20px; + input { + color: ${neutralColors.gray[900]}; + border-radius: 8px !important; + border: 1px solid ${neutralColors.gray[300]} !important; + } `; const Percentage = styled(InputSuffix)` @@ -129,16 +142,19 @@ const OptionWrapper = styled(GLink)<{ $isSelected: boolean }>` display: flex !important; justify-content: center; align-items: center; - color: ${brandColors.giv[500]}; + color: ${brandColors.giv[500]} !important; cursor: pointer; `; const Options = styled(Flex)` - gap: 8px; + gap: 16px; `; const Container = styled.div` margin: 16px 0 13px; + border-radius: 8px; + border: 1px solid ${neutralColors.gray[300]}; + padding: 16px; `; export default DonateToGiveth; diff --git a/src/components/views/donate/DonationCard.tsx b/src/components/views/donate/DonationCard.tsx index 7495dc964f..36183e8ea2 100644 --- a/src/components/views/donate/DonationCard.tsx +++ b/src/components/views/donate/DonationCard.tsx @@ -1,18 +1,26 @@ -import { B, P, neutralColors, Flex } from '@giveth/ui-design-system'; -import { FC, useState, useEffect } from 'react'; +import { + B, + P, + neutralColors, + Flex, + SublineBold, + brandColors, +} from '@giveth/ui-design-system'; +import React, { FC, useState, useEffect } from 'react'; import styled, { css } from 'styled-components'; import { useIntl } from 'react-intl'; import { useRouter } from 'next/router'; import { isAddress } from 'viem'; import { captureException } from '@sentry/nextjs'; +import Image from 'next/image'; import { Shadow } from '@/components/styled-components/Shadow'; import { RecurringDonationCard } from './Recurring/RecurringDonationCard'; -import OneTimeDonationCard from './OnTime/OneTimeDonationCard'; +import OneTimeDonationCard from '@/components/views/donate/OneTime/OneTimeDonationCard'; import config from '@/configuration'; import { useDonateData } from '@/context/donate.context'; import { ChainType } from '@/types/config'; import { IconWithTooltip } from '@/components/IconWithToolTip'; -import { QRDonationCard } from './OnTime/SelectTokenModal/QRCodeDonation/QRDonationCard'; +import { QRDonationCard } from '@/components/views/donate/OneTime/SelectTokenModal/QRCodeDonation/QRDonationCard'; import { client } from '@/apollo/apolloClient'; import { PROJECT_ACCEPTED_TOKENS } from '@/apollo/gql/gqlProjects'; import { showToastError } from '@/lib/helpers'; @@ -22,7 +30,7 @@ import { } from '@/apollo/types/gqlTypes'; export enum ETabs { - ONE_TIME = 'on-time', + ONE_TIME = 'one-time', RECURRING = 'recurring', } @@ -53,6 +61,7 @@ export const DonationCard: FC = ({ address.chainType === ChainType.EVM && address.networkId === config.OPTIMISM_NETWORK_NUMBER, ); + const isEndaomentProject = project?.organization?.label === 'endaoment'; const isOwnerOnEVM = project?.adminUser?.walletAddress && @@ -65,6 +74,24 @@ export const DonationCard: FC = ({ const disableRecurringDonations = organization?.disableRecurringDonations; + const hasStellarAddress = addresses?.some( + address => address.chainType === ChainType.STELLAR, + ); + + const handleQRDonation = () => { + setIsQRDonation(true); + router.push( + { + query: { + ...router.query, + chain: ChainType.STELLAR.toLowerCase(), + }, + }, + undefined, + { shallow: true }, + ); + }; + useEffect(() => { client .query({ @@ -93,16 +120,31 @@ export const DonationCard: FC = ({ // Check if the 'tab' query parameter is not present in the URL and project 'hasOpAddress' is true. // If both conditions are met, set the active tab to 'RECURRING' using the setTab function. // This ensures that the 'RECURRING' tab is active by default if project has Op Address. - useEffect(() => { - if (!router.query.tab && hasOpAddress) { - setTab(ETabs.RECURRING); - } - }, [router.query, hasOpAddress]); + // + // this feature needs some more polish, commenting this out for now --mitch + // useEffect(() => { + // if (!router.query.tab && hasOpAddress && !isEndaomentProject) { + // setTab(ETabs.RECURRING); + // } + // }, [router.query, hasOpAddress, isEndaomentProject]); return ( {!isQRDonation ? ( <> + {hasStellarAddress && ( + + stellar + {formatMessage({ + id: 'label.try_donating_with_stellar', + })} + + )} {formatMessage({ id: 'label.how_do_you_want_to_donate', @@ -177,7 +219,6 @@ export const DonationCard: FC<IDonationCardProps> = ({ <TabWrapper> {tab === ETabs.ONE_TIME && ( <OneTimeDonationCard - setIsQRDonation={setIsQRDonation} acceptedTokens={acceptedTokens} /> )} @@ -196,12 +237,28 @@ export const DonationCard: FC<IDonationCardProps> = ({ ); }; +const QRToastLink = styled(SublineBold)` + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + gap: 12px; + padding-block: 8px; + padding-left: 16px; + margin-block: 16px; + margin-top: 0; + background-color: transparent; + border: 1px solid ${neutralColors.gray[400]}; + color: ${brandColors.giv[500]} !important; + border-radius: 8px; + font-weight: 500 !important; +`; + export const DonationCardWrapper = styled(Flex)` flex-direction: column; gap: 16px; padding: 24px; border-radius: 16px; - align-items: flex-start; background: ${neutralColors.gray[100]}; box-shadow: ${Shadow.Neutral[400]}; align-items: stretch; @@ -209,7 +266,7 @@ export const DonationCardWrapper = styled(Flex)` `; const Title = styled(B)` - color: ${neutralColors.gray[800]}; + color: ${neutralColors.gray[800]} !important; text-align: left; `; @@ -227,6 +284,7 @@ interface ITab { } const Tab = styled(BaseTab)<ITab>` + font-weight: 500 !important; cursor: pointer; ${props => props.$selected && diff --git a/src/components/views/donate/OnTime/DonateQFEligibleNetworks.tsx b/src/components/views/donate/OnTime/DonateQFEligibleNetworks.tsx deleted file mode 100644 index 855fc9db53..0000000000 --- a/src/components/views/donate/OnTime/DonateQFEligibleNetworks.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import { - Caption, - IconExternalLink16, - IconInfoFilled16, - brandColors, - neutralColors, - Flex, -} from '@giveth/ui-design-system'; -import React, { useState } from 'react'; -import styled from 'styled-components'; -import { useIntl } from 'react-intl'; -import SwitchNetwork from '@/components/modals/SwitchNetwork'; -import { useDonateData } from '@/context/donate.context'; -import { getActiveRound } from '@/helpers/qf'; -import { getChainName } from '@/lib/network'; -import { ChainType } from '@/types/config'; -import links from '@/lib/constants/links'; - -const DonateQFEligibleNetworks = () => { - const [showModal, setShowModal] = useState(false); - const { project } = useDonateData(); - const { formatMessage } = useIntl(); - - const { activeStartedRound } = getActiveRound(project.qfRounds); - - const eligibleChainNames = activeStartedRound?.eligibleNetworks.map( - network => getChainName(network), - ); - - const eligibleNetworksWithChainType = - activeStartedRound?.eligibleNetworks.map(network => ({ - networkId: network, - chainType: ChainType.EVM, - })); - - const chainsString = eligibleChainNames?.join(' & '); - - return ( - <Container> - <MakeDonationTitle> - <Flex $alignItems='center' gap='4px'> - <IconInfoFilled16 /> - {formatMessage({ - id: 'label.make_your_donation_eligible_for_matching', - })} - </Flex> - </MakeDonationTitle> - <MakeDonationDescription> - {formatMessage({ id: 'label.donations_made_on' })} -  <BoldCaption>{chainsString}</BoldCaption>  - {formatMessage({ id: 'label.are_eligible_to_be_matched' })} - </MakeDonationDescription> - <ActionsRow $justifyContent='flex-start' $alignItems='center'> - <StyledCaption onClick={() => setShowModal(true)}> - {formatMessage({ id: 'label.switch_network' })} - </StyledCaption> - <Divider /> - <ExternalLink - href={links.ACROSS_BRIDGE} - target='_blank' - rel='noreferrer noopener' - > - <StyledCaption> - {formatMessage({ id: 'label.bridge_tokens' })} - </StyledCaption> - <IconExternalLink16 /> - </ExternalLink> - </ActionsRow> - {showModal && ( - <SwitchNetwork - setShowModal={setShowModal} - customNetworks={eligibleNetworksWithChainType} - /> - )} - </Container> - ); -}; - -const Container = styled.div` - margin-top: 8px; - border: 1px solid ${brandColors.giv[500]}; - border-radius: 8px; - padding: 16px 16px; -`; - -const MakeDonationTitle = styled(Caption)` - color: ${brandColors.giv[500]}; -`; - -const MakeDonationDescription = styled(Caption)` - width: 100%; - display: inline-block; - margin-top: 8px; - padding-top: 8px; - border-top: 1px solid ${neutralColors.gray[400]}; - color: ${neutralColors.gray[700]}; -`; - -const BoldCaption = styled(Caption)` - font-weight: 500; - display: inline; -`; - -const StyledCaption = styled(Caption)` - cursor: pointer; -`; - -const ActionsRow = styled(Flex)` - margin-top: 8px; - gap: 16px; - color: ${brandColors.pinky[500]}; -`; - -const Divider = styled.div` - border-right: 1px solid ${neutralColors.gray[400]}; - width: 0px; - height: 16px; -`; - -const ExternalLink = styled.a` - text-decoration: none; - display: flex; - align-items: center; - gap: 4px; -`; - -export default DonateQFEligibleNetworks; diff --git a/src/components/views/donate/OnTime/EstimatedMatchingToast.tsx b/src/components/views/donate/OnTime/EstimatedMatchingToast.tsx deleted file mode 100644 index 6c39277075..0000000000 --- a/src/components/views/donate/OnTime/EstimatedMatchingToast.tsx +++ /dev/null @@ -1,163 +0,0 @@ -import styled from 'styled-components'; -import { - B, - Caption, - IconHelpFilled16, - IconAlertTriangleFilled, - neutralColors, - semanticColors, - Subline, - FlexCenter, -} from '@giveth/ui-design-system'; -import React from 'react'; -import { useIntl } from 'react-intl'; -import { formatUnits } from 'viem'; -import Divider from '@/components/Divider'; -import { TooltipContent } from '@/components/modals/HarvestAll.sc'; -import { IconWithTooltip } from '@/components/IconWithToolTip'; -import { IProject } from '@/apollo/types/types'; -import { - calculateEstimatedMatchingWithDonationAmount, - getActiveRound, -} from '@/helpers/qf'; -import { IProjectAcceptedToken } from '@/apollo/types/gqlTypes'; -import { useTokenPrice } from '@/hooks/useTokenPrice'; -import { formatDonation } from '@/helpers/number'; -import { formatBalance, truncateToDecimalPlaces } from '@/lib/helpers'; - -interface IEstimatedMatchingToast { - projectData: IProject; - amount: bigint; - token?: IProjectAcceptedToken; -} - -const EstimatedMatchingToast: React.FC<IEstimatedMatchingToast> = ({ - projectData, - token, - amount, -}) => { - const { formatMessage, locale } = useIntl(); - const { estimatedMatching, qfRounds } = projectData || {}; - const { allProjectsSum, matchingPool, projectDonationsSqrtRootSum } = - estimatedMatching || {}; - - const tokenPrice = useTokenPrice(token); - - const { activeStartedRound } = getActiveRound(qfRounds); - const { - allocatedFundUSDPreferred, - allocatedFundUSD, - allocatedTokenSymbol, - minimumValidUsdValue, - maximumReward, - } = activeStartedRound || {}; - - const decimals = token?.decimals || 18; - - const amountInUsd = - (tokenPrice || 0) * - (truncateToDecimalPlaces(formatUnits(amount, decimals), decimals) || 0); - - const esMatching = calculateEstimatedMatchingWithDonationAmount( - amountInUsd, - projectDonationsSqrtRootSum, - allProjectsSum, - allocatedFundUSDPreferred ? allocatedFundUSD : matchingPool, - maximumReward, - ); - - const isAboveMinValidUsdValue = - minimumValidUsdValue != null - ? amountInUsd >= minimumValidUsdValue - : true; - - const borderColor = isAboveMinValidUsdValue - ? semanticColors.jade['500'] - : semanticColors.golden['500']; - - const textColor = isAboveMinValidUsdValue - ? semanticColors.jade['700'] - : semanticColors.golden['500']; - - const tooltipIcon = isAboveMinValidUsdValue ? ( - <IconHelpFilled16 color={textColor} /> - ) : ( - <IconAlertTriangleFilled color={textColor} /> - ); - - const formattedDonation = isAboveMinValidUsdValue - ? `${formatDonation( - esMatching, - allocatedFundUSDPreferred ? '$' : '', - locale, - true, - )} ${allocatedFundUSDPreferred ? '' : ` ${allocatedTokenSymbol}`}` - : '---'; - - const bottomText = isAboveMinValidUsdValue - ? formatMessage({ id: 'page.donate.matching_toast.bottom_valid' }) - : formatMessage({ - id: 'page.donate.matching_toast.bottom_invalid_p1', - }) + - ' $' + - formatBalance(minimumValidUsdValue) + - ' ' + - formatMessage({ - id: 'page.donate.matching_toast.bottom_invalid_p2', - }); - - return ( - <Wrapper style={{ borderColor }}> - <Upper style={{ color: textColor }}> - <EstimatedMatching> - <Caption $medium> - {formatMessage({ - id: isAboveMinValidUsdValue - ? 'page.donate.matching_toast.upper_valid' - : 'page.donate.matching_toast.upper_invalid', - })} - </Caption> - <IconWithTooltip icon={tooltipIcon} direction='top'> - {isAboveMinValidUsdValue && ( - <TooltipContent> - {formatMessage({ - id: 'component.qf-section.tooltip_polygon', - })} - </TooltipContent> - )} - </IconWithTooltip> - </EstimatedMatching> - <B>{formattedDonation}</B> - </Upper> - <Divider /> - <Bottom>{bottomText}</Bottom> - </Wrapper> - ); -}; - -const EstimatedMatching = styled(FlexCenter)` - gap: 4px; - > *:last-child { - margin-top: 3px; - } -`; - -const Bottom = styled(Subline)` - color: ${neutralColors.gray['800']}; - margin-top: 4px; -`; - -const Upper = styled.div` - margin-bottom: 4px; - display: flex; - justify-content: space-between; -`; - -const Wrapper = styled.div` - border: 1px solid; - border-radius: 8px; - padding: 16px; - margin-top: 8px; -`; - -export default EstimatedMatchingToast; diff --git a/src/components/views/donate/OnTime/DonateModal.tsx b/src/components/views/donate/OneTime/DonateModal.tsx similarity index 94% rename from src/components/views/donate/OnTime/DonateModal.tsx rename to src/components/views/donate/OneTime/DonateModal.tsx index fd9b8b3654..5056cf274d 100644 --- a/src/components/views/donate/OnTime/DonateModal.tsx +++ b/src/components/views/donate/OneTime/DonateModal.tsx @@ -9,10 +9,15 @@ import { FlexCenter, } from '@giveth/ui-design-system'; import { useIntl } from 'react-intl'; -import { Chain } from 'viem'; +import { Chain, formatUnits } from 'viem'; import StorageLabel, { getWithExpiry } from '@/lib/localStorage'; import { Modal } from '@/components/modals/Modal'; -import { compareAddresses, formatTxLink, showToastError } from '@/lib/helpers'; +import { + compareAddresses, + formatTxLink, + showToastError, + truncateToDecimalPlaces, +} from '@/lib/helpers'; import { mediaQueries } from '@/lib/constants/constants'; import { IMeGQL, IProjectAcceptedToken } from '@/apollo/types/gqlTypes'; import { IModal } from '@/types/common'; @@ -36,7 +41,7 @@ import { ChainType } from '@/types/config'; import { IProject, IWalletAddress } from '@/apollo/types/types'; import { useCreateSolanaDonation } from '@/hooks/useCreateSolanaDonation'; import { useTokenPrice } from '@/hooks/useTokenPrice'; -import { calcDonationShare } from '@/components/views/donate/helpers'; +import { calcDonationShare } from '@/components/views/donate/common/helpers'; import { Spinner } from '@/components/Spinner'; import { FETCH_GIVETH_PROJECT_BY_ID } from '@/apollo/gql/gqlProjects'; import createGoogleTagEventPurchase from '@/helpers/googleAnalytics'; @@ -82,13 +87,14 @@ const DonateModal: FC<IDonateModalProps> = props => { walletChainType, walletAddress: address, } = useGeneralWallet(); + const chainId = (chain as Chain)?.id; const chainName = (chain as Chain)?.name; const dispatch = useAppDispatch(); const { isAnimating, closeModal } = useModalAnimation(setShowModal); const isDonatingToGiveth = donationToGiveth > 0 && givethDonationAmount > 0; const { formatMessage } = useIntl(); - const { setSuccessDonation, project } = useDonateData(); + const { setSuccessDonation, project, activeStartedRound } = useDonateData(); const [donating, setDonating] = useState(false); const [secondTxStatus, setSecondTxStatus] = useState<EToastType>(); @@ -123,6 +129,19 @@ const DonateModal: FC<IDonateModalProps> = props => { const tokenPrice = useTokenPrice(token); + const isOnEligibleNetworks = activeStartedRound?.eligibleNetworks?.includes( + (chain as Chain).id, + ); + const donationUsdValue = + (tokenPrice || 0) * + (truncateToDecimalPlaces( + formatUnits(amount, token.decimals), + token.decimals, + ) || 0); + const includeInQF = + activeStartedRound && + isOnEligibleNetworks && + donationUsdValue >= (activeStartedRound.minimumValidUsdValue || 0); const chainvineReferred = getWithExpiry(StorageLabel.CHAINVINEREFERRED); const { title, addresses } = project || {}; @@ -189,6 +208,7 @@ const DonateModal: FC<IDonateModalProps> = props => { closeModal(); setSuccessDonation({ txHash: txHashArray, + excludeFromQF: !includeInQF, givBackEligible, chainId, }); diff --git a/src/components/views/donate/OneTime/EstimatedMatchingToast.tsx b/src/components/views/donate/OneTime/EstimatedMatchingToast.tsx new file mode 100644 index 0000000000..76db0f598c --- /dev/null +++ b/src/components/views/donate/OneTime/EstimatedMatchingToast.tsx @@ -0,0 +1,109 @@ +import styled from 'styled-components'; +import { + B, + Caption, + FlexCenter, + IconHelpFilled16, + neutralColors, + semanticColors, +} from '@giveth/ui-design-system'; +import React, { FC } from 'react'; +import { useIntl } from 'react-intl'; +import { formatUnits } from 'viem'; +import { TooltipContent } from '@/components/modals/HarvestAll.sc'; +import { IconWithTooltip } from '@/components/IconWithToolTip'; +import { IProject } from '@/apollo/types/types'; +import { + calculateEstimatedMatchingWithDonationAmount, + getActiveRound, +} from '@/helpers/qf'; +import { IProjectAcceptedToken } from '@/apollo/types/gqlTypes'; +import { formatDonation } from '@/helpers/number'; +import { truncateToDecimalPlaces } from '@/lib/helpers'; + +interface IEstimatedMatchingToast { + projectData: IProject; + amount: bigint; + token?: IProjectAcceptedToken; + tokenPrice?: number; + isStellar?: boolean; + show?: boolean; +} + +const EstimatedMatchingToast: FC<IEstimatedMatchingToast> = ({ + projectData, + token, + amount, + tokenPrice, + isStellar, + show, +}) => { + const { formatMessage, locale } = useIntl(); + const { estimatedMatching, qfRounds } = projectData || {}; + const { allProjectsSum, matchingPool, projectDonationsSqrtRootSum } = + estimatedMatching || {}; + + const { activeStartedRound } = getActiveRound(qfRounds); + const { + allocatedFundUSDPreferred, + allocatedFundUSD, + allocatedTokenSymbol, + maximumReward, + } = activeStartedRound || {}; + + const decimals = isStellar ? 18 : token?.decimals || 18; + const amountInUsd = + (tokenPrice || 0) * + (truncateToDecimalPlaces(formatUnits(amount, decimals), decimals) || 0); + + const esMatching = calculateEstimatedMatchingWithDonationAmount( + amountInUsd, + projectDonationsSqrtRootSum, + allProjectsSum, + allocatedFundUSDPreferred ? allocatedFundUSD : matchingPool, + maximumReward, + ); + + const formattedDonation = `${formatDonation( + esMatching, + allocatedFundUSDPreferred ? '$' : '', + locale, + true, + )} ${allocatedFundUSDPreferred ? '' : ` ${allocatedTokenSymbol}`}`; + + return ( + <Wrapper show={show}> + <FlexCenter gap='5px'> + <Caption $medium> + {formatMessage({ id: 'label.estimated_matching' })} + </Caption> + <IconWithTooltip + style={{ marginBottom: '-5px' }} + icon={<IconHelpFilled16 />} + direction='top' + > + <TooltipContent> + {formatMessage({ + id: 'component.qf-section.tooltip_polygon', + })} + </TooltipContent> + </IconWithTooltip> + </FlexCenter> + <B>{formattedDonation}</B> + </Wrapper> + ); +}; + +const Wrapper = styled.div<{ show?: boolean }>` + display: flex; + padding: 4px 16px 8px 16px; + justify-content: space-between; + align-items: center; + border-radius: 8px 8px 0 0; + background: ${neutralColors.gray[200]}; + color: ${semanticColors.jade[700]}; + margin-bottom: -5px; + opacity: ${({ show }) => (show ? 1 : 0)}; +`; + +export default EstimatedMatchingToast; diff --git a/src/components/views/donate/OnTime/OneTimeDonationCard.tsx b/src/components/views/donate/OneTime/OneTimeDonationCard.tsx similarity index 61% rename from src/components/views/donate/OnTime/OneTimeDonationCard.tsx rename to src/components/views/donate/OneTime/OneTimeDonationCard.tsx index 748d807c0f..0ed6f35989 100644 --- a/src/components/views/donate/OnTime/OneTimeDonationCard.tsx +++ b/src/components/views/donate/OneTime/OneTimeDonationCard.tsx @@ -1,7 +1,6 @@ import styled from 'styled-components'; import React, { FC, useEffect, useMemo, useState } from 'react'; import { useIntl } from 'react-intl'; -import { useRouter } from 'next/router'; import { B, brandColors, @@ -9,14 +8,16 @@ import { Flex, IconCaretDown16, IconRefresh16, + IconWalletOutline24, neutralColors, + OutlineButton, semanticColors, + SublineBold, } from '@giveth/ui-design-system'; // @ts-ignore import { Address, Chain, formatUnits, zeroAddress } from 'viem'; import { useBalance, useEstimateFeesPerGas, useEstimateGas } from 'wagmi'; import { setShowWelcomeModal } from '@/features/modal/modal.slice'; -import CheckBox from '@/components/Checkbox'; import { InsufficientFundModal } from '@/components/modals/InsufficientFund'; import config from '@/configuration'; @@ -28,8 +29,7 @@ import { IProjectAcceptedToken } from '@/apollo/types/gqlTypes'; import { calcDonationShare, prepareTokenList, -} from '@/components/views/donate/helpers'; -import GIVBackToast from '@/components/views/donate/GIVBackToast'; +} from '@/components/views/donate/common/helpers'; import { DonateWrongNetwork } from '@/components/modals/DonateWrongNetwork'; import { useAppDispatch, useAppSelector } from '@/features/hooks'; import DonateToGiveth from '@/components/views/donate/DonateToGiveth'; @@ -37,34 +37,38 @@ import SaveGasFees from './SaveGasFees'; import SwitchToAcceptedChain from '@/components/views/donate/SwitchToAcceptedChain'; import { useDonateData } from '@/context/donate.context'; import { useModalCallback } from '@/hooks/useModalCallback'; -import DonateQFEligibleNetworks from './DonateQFEligibleNetworks'; import { getActiveRound } from '@/helpers/qf'; import { useGeneralWallet } from '@/providers/generalWalletProvider'; import { ChainType } from '@/types/config'; -import { INetworkIdWithChain } from '../common.types'; +import { INetworkIdWithChain } from '../common/common.types'; import DonateModal from './DonateModal'; import QFModal from './QFModal'; -import EstimatedMatchingToast from '@/components/views/donate/OnTime/EstimatedMatchingToast'; +import EstimatedMatchingToast from '@/components/views/donate/OneTime/EstimatedMatchingToast'; import TotalDonation from './TotalDonation'; import { + BadgesBase, + ForEstimatedMatchingAnimation, GLinkStyled, IconWrapper, Input, InputWrapper, SelectTokenPlaceHolder, SelectTokenWrapper, -} from '../Recurring/RecurringDonationCard'; +} from '../common/common.styled'; import { TokenIcon } from '../TokenIcon/TokenIcon'; import { SelectTokenModal } from './SelectTokenModal/SelectTokenModal'; import { Spinner } from '@/components/Spinner'; import { useSolanaBalance } from '@/hooks/useSolanaBalance'; import { isWalletSanctioned } from '@/services/donation'; import SanctionModal from '@/components/modals/SanctionedModal'; +import { useTokenPrice } from '@/hooks/useTokenPrice'; +import EligibilityBadges from '@/components/views/donate/common/EligibilityBadges'; +import DonateAnonymously from '@/components/views/donate/common/DonateAnonymously'; +import { GIVBACKS_DONATION_QUALIFICATION_VALUE_USD } from '@/lib/constants/constants'; const CryptoDonation: FC<{ - setIsQRDonation: (isQRDonation: boolean) => void; acceptedTokens: IProjectAcceptedToken[] | undefined; -}> = ({ acceptedTokens, setIsQRDonation }) => { +}> = ({ acceptedTokens }) => { const { chain, walletChainType, @@ -73,7 +77,6 @@ const CryptoDonation: FC<{ } = useGeneralWallet(); const { formatMessage } = useIntl(); - const router = useRouter(); const { isSignedIn } = useAppSelector(state => state.user); const { project, hasActiveQFRound, selectedOneTimeToken } = useDonateData(); @@ -139,15 +142,13 @@ const CryptoDonation: FC<{ }); const tokenDecimals = selectedOneTimeToken?.decimals || 18; - const projectIsGivBackEligible = !!isGivbackEligible; const { activeStartedRound } = getActiveRound(project.qfRounds); const networkId = (chain as Chain)?.id; - const isOnEligibleNetworks = + const isOnQFEligibleNetworks = networkId && activeStartedRound?.eligibleNetworks?.includes(networkId); - const hasStellarAddress = addresses?.some( - address => address.chainType === ChainType.STELLAR, - ); + + const tokenPrice = useTokenPrice(selectedOneTimeToken); useEffect(() => { validateSanctions(); @@ -198,7 +199,7 @@ const CryptoDonation: FC<{ return false; } }); - const acceptedChainsWithChaintypeAndNetworkId: INetworkIdWithChain[] = + const acceptedChainsWithChainTypeAndNetworkId: INetworkIdWithChain[] = []; addresses?.forEach(a => { if ( @@ -206,20 +207,20 @@ const CryptoDonation: FC<{ a.chainType === ChainType.EVM ) { if (acceptedEvmTokensNetworkIds.has(a.networkId!)) { - acceptedChainsWithChaintypeAndNetworkId.push({ + acceptedChainsWithChainTypeAndNetworkId.push({ networkId: a.networkId!, chainType: ChainType.EVM, }); } } else if (acceptedNonEvmTokenChainTypes.has(a.chainType)) { - acceptedChainsWithChaintypeAndNetworkId.push({ + acceptedChainsWithChainTypeAndNetworkId.push({ networkId: a.networkId!, chainType: a.chainType!, }); } }); - setAcceptedChains(acceptedChainsWithChaintypeAndNetworkId); + setAcceptedChains(acceptedChainsWithChainTypeAndNetworkId); if (filteredTokens.length < 1) { setShowChangeNetworkModal(true); } @@ -249,7 +250,7 @@ const CryptoDonation: FC<{ } if ( hasActiveQFRound && - !isOnEligibleNetworks && + !isOnQFEligibleNetworks && selectedOneTimeToken?.chainType === ChainType.EVM ) { setShowQFModal(true); @@ -285,7 +286,7 @@ const CryptoDonation: FC<{ const { data: estimatedGasPrice } = useEstimateFeesPerGas(estimatedGasFeeObj); - const gasfee = useMemo((): bigint => { + const gasFee = useMemo((): bigint => { if ( selectedOneTimeToken?.address !== zeroAddress || !estimatedGas || @@ -300,32 +301,18 @@ const CryptoDonation: FC<{ selectedOneTimeToken?.address, ]); - const handleQRDonation = () => { - setIsQRDonation(true); - router.push( - { - query: { - ...router.query, - chain: ChainType.STELLAR.toLowerCase(), - }, - }, - undefined, - { shallow: true }, - ); - }; - useEffect(() => { if ( - amount > selectedTokenBalance - gasfee && + amount > selectedTokenBalance - gasFee && amount < selectedTokenBalance && selectedOneTimeToken?.address === zeroAddress && - gasfee > 0n + gasFee > 0n ) { setInsufficientGasFee(true); } else { setInsufficientGasFee(false); } - }, [selectedTokenBalance, amount, selectedOneTimeToken?.address, gasfee]); + }, [selectedTokenBalance, amount, selectedOneTimeToken?.address, gasFee]); const validateSanctions = async () => { if (project?.organization?.label === 'endaoment' && address) { @@ -339,7 +326,7 @@ const CryptoDonation: FC<{ }; const amountErrorText = useMemo(() => { - const totalAmount = Number(formatUnits(gasfee, tokenDecimals)).toFixed( + const totalAmount = Number(formatUnits(gasFee, tokenDecimals)).toFixed( 10, ); const tokenSymbol = selectedOneTimeToken?.symbol; @@ -350,17 +337,35 @@ const CryptoDonation: FC<{ tokenSymbol, }, ); - }, [gasfee, tokenDecimals, selectedOneTimeToken?.symbol, formatMessage]); + }, [gasFee, tokenDecimals, selectedOneTimeToken?.symbol, formatMessage]); // We need givethDonationAmount here because we need to calculate the donation share // for Giveth. If user want to donate minimal amount to projecct, the donation share for Giveth // has to be 0, disabled in UI and DonationModal - const { givethDonation: givethDonationAmount } = calcDonationShare( + const { + givethDonation: givethDonationAmount, + projectDonation: projectDonationAmount, + } = calcDonationShare( amount, donationToGiveth, selectedOneTimeToken?.decimals ?? 18, ); + const decimals = selectedOneTimeToken?.decimals || 18; + const donationUsdValue = + (tokenPrice || 0) * + (truncateToDecimalPlaces(formatUnits(amount, decimals), decimals) || 0); + const isDonationMatched = + !!activeStartedRound && + isOnQFEligibleNetworks && + donationUsdValue >= (activeStartedRound?.minimumValidUsdValue || 0); + const showEstimatedMatching = + hasActiveQFRound && + !!isOnQFEligibleNetworks && + !!selectedTokenBalance && + !!isDonationMatched; + const selectTokenDisabled = !isConnected || erc20List?.length === 0; + return ( <MainContainer> {isSanctioned && ( @@ -398,8 +403,11 @@ const CryptoDonation: FC<{ givethDonationAmount={givethDonationAmount} anonymous={anonymous} givBackEligible={ - projectIsGivBackEligible && - selectedOneTimeToken.isGivbackEligible + isGivbackEligible && + selectedOneTimeToken.isGivbackEligible && + tokenPrice !== undefined && + tokenPrice * projectDonationAmount >= + GIVBACKS_DONATION_QUALIFICATION_VALUE_USD } /> )} @@ -410,170 +418,231 @@ const CryptoDonation: FC<{ /> )} <SaveGasFees acceptedChains={acceptedChains} /> - {hasStellarAddress && ( - <QRToastLink onClick={handleQRDonation}> - {config.NETWORKS_CONFIG[ChainType.STELLAR]?.chainLogo(32)} + {!isConnected && ( + <ConnectWallet> + <IconWalletOutline24 color={neutralColors.gray[700]} /> {formatMessage({ - id: 'label.try_donating_wuth_stellar', + id: 'label.please_connect_your_wallet', })} - </QRToastLink> - )} - <Flex $flexDirection='column' gap='8px'> - <InputWrapper> - <SelectTokenWrapper - $alignItems='center' - $justifyContent='space-between' - onClick={() => setShowSelectTokenModal(true)} - > - {selectedOneTimeToken ? ( - <Flex gap='8px' $alignItems='center'> - <TokenIcon - symbol={selectedOneTimeToken.symbol} - size={24} - /> - <TokenSymbol> - {selectedOneTimeToken.symbol} - </TokenSymbol> - </Flex> - ) : ( - <SelectTokenPlaceHolder> - {formatMessage({ - id: 'label.select_token', - })} - </SelectTokenPlaceHolder> - )} - <IconCaretDown16 /> - </SelectTokenWrapper> - <Input - amount={amount} - setAmount={setAmount} - disabled={selectedOneTimeToken === undefined} - decimals={selectedOneTimeToken?.decimals} - /> - </InputWrapper> - <Flex gap='4px' $alignItems='center'> - <GLinkStyled - size='Small' - onClick={() => setAmount(selectedTokenBalance - gasfee)} - > - {formatMessage({ - id: 'label.available', - })} - :{' '} - {selectedOneTimeToken - ? truncateToDecimalPlaces( - formatUnits( - selectedTokenBalance, - tokenDecimals, - ), - tokenDecimals / 3, - ) - : 0.0} - </GLinkStyled> - <IconWrapper onClick={() => !isRefetching && refetch()}> - {isRefetching ? ( - <Spinner size={16} /> - ) : ( - <IconRefresh16 /> - )} - </IconWrapper> - {insufficientGasFee && ( - <WarnError>{amountErrorText}</WarnError> - )} - </Flex> - </Flex> - {hasActiveQFRound && !isOnEligibleNetworks && walletChainType && ( - <DonateQFEligibleNetworks /> + </ConnectWallet> )} - {hasActiveQFRound && isOnEligibleNetworks && ( - <EstimatedMatchingToast - projectData={project} + {!selectTokenDisabled && ( + <EligibilityBadges token={selectedOneTimeToken} amount={amount} + tokenPrice={tokenPrice} + style={{ margin: '12px 0 24px' }} /> )} - {!noDonationSplit ? ( - <DonateToGiveth - setDonationToGiveth={setDonationToGiveth} - donationToGiveth={donationToGiveth} - givethDonationAmount={givethDonationAmount} - title={ - formatMessage({ id: 'label.donation_to' }) + ' Giveth' - } - /> - ) : ( - <br /> - )} - {selectedOneTimeToken && ( - <GIVBackToast - projectEligible={projectIsGivBackEligible} - tokenEligible={selectedOneTimeToken.isGivbackEligible} - /> - )} - {!noDonationSplit ? ( - <TotalDonation - donationToGiveth={donationToGiveth} - totalDonation={amount} - projectTitle={projectTitle} - token={selectedOneTimeToken} - isActive={!donationDisabled} - /> - ) : ( - <EmptySpace /> - )} - {!isActive && ( - <InlineToast - type={EToastType.Warning} - message={formatMessage({ - id: 'label.this_project_is_not_active', - })} - /> - )} - {isConnected && ( - <MainButton - id='Donate_Final' - label={formatMessage({ id: 'label.donate' })} - disabled={donationDisabled} - size='medium' - onClick={handleDonate} - /> - )} - {!isConnected && ( - <MainButton - label={formatMessage({ - id: 'component.button.connect_wallet', - })} - onClick={() => dispatch(setShowWelcomeModal(true))} - /> - )} - <CheckBoxContainer> - <CheckBox - label={formatMessage({ - id: 'label.make_it_anonymous', - })} - checked={anonymous} - onChange={() => setAnonymous(!anonymous)} - size={14} - /> - <div> - {formatMessage({ - id: 'component.tooltip.donate_anonymously', - })} - </div> - </CheckBoxContainer> - {showSelectTokenModal && ( - <SelectTokenModal - setShowModal={setShowSelectTokenModal} - tokens={erc20List} - acceptCustomToken={ - project.organization?.supportCustomTokens - } + <EstimatedMatchingToast + projectData={project} + token={selectedOneTimeToken} + amount={amount} + tokenPrice={tokenPrice} + show={showEstimatedMatching} + /> + <ForEstimatedMatchingAnimation + showEstimatedMatching={showEstimatedMatching} + > + <FlexStyled + $flexDirection='column' + gap='8px' + disabled={selectTokenDisabled} + > + <InputWrapper> + <SelectTokenWrapper + $alignItems='center' + $justifyContent='space-between' + onClick={() => + !selectTokenDisabled && + setShowSelectTokenModal(true) + } + disabled={selectTokenDisabled} + style={{ + color: + selectedOneTimeToken || selectTokenDisabled + ? 'inherit' + : brandColors.giv[500], + }} + > + {selectedOneTimeToken ? ( + <Flex gap='8px' $alignItems='center'> + <TokenIcon + symbol={selectedOneTimeToken.symbol} + size={24} + /> + <TokenSymbol> + {selectedOneTimeToken.symbol} + </TokenSymbol> + </Flex> + ) : ( + <SelectTokenPlaceHolder> + {formatMessage({ + id: 'label.select_token', + })} + </SelectTokenPlaceHolder> + )} + <IconCaretDown16 /> + </SelectTokenWrapper> + <Input + amount={amount} + setAmount={setAmount} + disabled={selectedOneTimeToken === undefined} + decimals={selectedOneTimeToken?.decimals} + /> + <DonationPrice + disabled={!selectedOneTimeToken || !isConnected} + > + {'$ ' + donationUsdValue.toFixed(2)} + </DonationPrice> + </InputWrapper> + {selectedOneTimeToken ? ( + <FlexStyled + gap='4px' + $alignItems='center' + disabled={!selectedOneTimeToken} + > + <GLinkStyled + size='Small' + onClick={() => + setAmount(selectedTokenBalance - gasFee) + } + > + {formatMessage({ + id: 'label.available', + })} + :{' '} + {selectedOneTimeToken + ? truncateToDecimalPlaces( + formatUnits( + selectedTokenBalance, + tokenDecimals, + ), + tokenDecimals / 3, + ) + : 0.0} + </GLinkStyled> + <IconWrapper + onClick={() => !isRefetching && refetch()} + > + {isRefetching ? ( + <Spinner size={16} /> + ) : ( + <IconRefresh16 /> + )} + </IconWrapper> + {insufficientGasFee && ( + <WarnError>{amountErrorText}</WarnError> + )} + </FlexStyled> + ) : ( + <div style={{ height: '21.5px' }} /> + )} + </FlexStyled> + {!noDonationSplit ? ( + <DonateToGiveth + setDonationToGiveth={setDonationToGiveth} + donationToGiveth={donationToGiveth} + title={ + formatMessage({ id: 'label.donate_to' }) + ' Giveth' + } + disabled={!selectedOneTimeToken || !isConnected} + /> + ) : ( + <br /> + )} + {!noDonationSplit ? ( + <TotalDonation + donationToGiveth={donationToGiveth} + totalDonation={amount} + projectTitle={projectTitle} + token={selectedOneTimeToken} + isActive={!donationDisabled} + /> + ) : ( + <EmptySpace /> + )} + {!isActive && ( + <InlineToast + type={EToastType.Warning} + message={formatMessage({ + id: 'label.this_project_is_not_active', + })} + /> + )} + {isConnected && + (donationDisabled ? ( + <OutlineButtonStyled + label={formatMessage({ id: 'label.donate' })} + disabled + size='medium' + /> + ) : ( + <MainButton + id='Donate_Final' + label={formatMessage({ id: 'label.donate' })} + size='medium' + onClick={handleDonate} + /> + ))} + {!isConnected && ( + <MainButton + label={formatMessage({ + id: 'component.button.connect_wallet', + })} + onClick={() => dispatch(setShowWelcomeModal(true))} + /> + )} + <DonateAnonymously + anonymous={anonymous} + setAnonymous={setAnonymous} + selectedToken={selectedOneTimeToken} /> - )} + {showSelectTokenModal && ( + <SelectTokenModal + setShowModal={setShowSelectTokenModal} + tokens={erc20List} + acceptCustomToken={ + project.organization?.supportCustomTokens + } + /> + )} + </ForEstimatedMatchingAnimation> </MainContainer> ); }; +const OutlineButtonStyled = styled(OutlineButton)` + width: 100%; +`; + +const DonationPrice = styled(SublineBold)<{ disabled?: boolean }>` + position: absolute; + right: 16px; + border-radius: 4px; + background: ${neutralColors.gray[300]}; + padding: 2px 8px !important; + margin: 16px 0px; + color: ${neutralColors.gray[700]} !important; + opacity: ${props => (props.disabled ? 0.4 : 1)}; + height: 22px; +`; + +const FlexStyled = styled(Flex)<{ disabled: boolean }>` + border-radius: 8px; + background-color: white; + ${props => + props.disabled && + ` + opacity: 0.5; + pointer-events: none; + `} +`; + +const ConnectWallet = styled(BadgesBase)` + margin: 12px 0 24px; +`; + const WarnError = styled.div` color: ${semanticColors.punch[500]}; font-size: 11px; @@ -604,28 +673,4 @@ const MainButton = styled(Button)` text-transform: uppercase; `; -export const CheckBoxContainer = styled.div` - margin-top: 16px; - > div:nth-child(2) { - color: ${neutralColors.gray[900]}; - font-size: 12px; - margin-top: 3px; - margin-left: 24px; - } -`; - -const QRToastLink = styled(Flex)` - cursor: pointer; - align-items: center; - gap: 12px; - padding-block: 8px; - padding-left: 16px; - margin-block: 16px; - background-color: ${semanticColors.blueSky[100]}; - color: ${semanticColors.blueSky[700]}; - border-radius: 8px; - border: 1px solid ${semanticColors.blueSky[300]}; - font-weight: 500; -`; - export default CryptoDonation; diff --git a/src/components/views/donate/OnTime/QFModal.tsx b/src/components/views/donate/OneTime/QFModal.tsx similarity index 100% rename from src/components/views/donate/OnTime/QFModal.tsx rename to src/components/views/donate/OneTime/QFModal.tsx diff --git a/src/components/views/donate/OnTime/SaveGasFees.tsx b/src/components/views/donate/OneTime/SaveGasFees.tsx similarity index 90% rename from src/components/views/donate/OnTime/SaveGasFees.tsx rename to src/components/views/donate/OneTime/SaveGasFees.tsx index a3d8d32716..c38b393fc1 100644 --- a/src/components/views/donate/OnTime/SaveGasFees.tsx +++ b/src/components/views/donate/OneTime/SaveGasFees.tsx @@ -7,8 +7,8 @@ import config from '@/configuration'; import { NetworkToast, SwitchCaption, -} from '@/components/views/donate/common.styled'; -import { INetworkIdWithChain } from '../common.types'; // Import the type +} from '@/components/views/donate/common/common.styled'; +import { INetworkIdWithChain } from '../common/common.types'; // Import the type import SwitchNetwork from '@/components/modals/SwitchNetwork'; const SaveGasFees: FC<{ acceptedChains: INetworkIdWithChain[] }> = ({ diff --git a/src/components/views/donate/OnTime/SelectTokenModal/QRCodeDonation/CopyConatainer.tsx b/src/components/views/donate/OneTime/SelectTokenModal/QRCodeDonation/CopyConatainer.tsx similarity index 100% rename from src/components/views/donate/OnTime/SelectTokenModal/QRCodeDonation/CopyConatainer.tsx rename to src/components/views/donate/OneTime/SelectTokenModal/QRCodeDonation/CopyConatainer.tsx diff --git a/src/components/views/donate/OnTime/SelectTokenModal/QRCodeDonation/QRDonationCard.tsx b/src/components/views/donate/OneTime/SelectTokenModal/QRCodeDonation/QRDonationCard.tsx similarity index 59% rename from src/components/views/donate/OnTime/SelectTokenModal/QRCodeDonation/QRDonationCard.tsx rename to src/components/views/donate/OneTime/SelectTokenModal/QRCodeDonation/QRDonationCard.tsx index 745cf1a89d..2097c19547 100644 --- a/src/components/views/donate/OnTime/SelectTokenModal/QRCodeDonation/QRDonationCard.tsx +++ b/src/components/views/donate/OneTime/SelectTokenModal/QRCodeDonation/QRDonationCard.tsx @@ -1,23 +1,29 @@ import React, { FC, useEffect, useState } from 'react'; import { useRouter } from 'next/router'; -import Image from 'next/image'; import styled from 'styled-components'; import { B, P, - Button, Flex, neutralColors, IconArrowLeft, mediaQueries, + IconWalletOutline24, + OutlineButton, + IconArrowRight16, + Button, + SublineBold, } from '@giveth/ui-design-system'; import { useIntl } from 'react-intl'; import { formatUnits } from 'viem'; +import { ethers } from 'ethers'; import { InputWrapper, SelectTokenWrapper, -} from '../../../Recurring/RecurringDonationCard'; + BadgesBase, + ForEstimatedMatchingAnimation, +} from '../../../common/common.styled'; import { TokenIconWithGIVBack } from '../../../TokenIcon/TokenIconWithGIVBack'; import { IProjectAcceptedToken } from '@/apollo/types/gqlTypes'; import { fetchPriceWithCoingeckoId } from '@/services/token'; @@ -25,7 +31,6 @@ import { ChainType } from '@/types/config'; import config from '@/configuration'; import { truncateToDecimalPlaces, - capitalizeAllWords, formatBalance, showToastError, } from '@/lib/helpers'; @@ -38,15 +43,17 @@ import StorageLabel from '@/lib/localStorage'; import InlineToast, { EToastType } from '@/components/toasts/InlineToast'; import { useAppSelector } from '@/features/hooks'; import { useModalCallback } from '@/hooks/useModalCallback'; -import links from '@/lib/constants/links'; +import { useGeneralWallet } from '@/providers/generalWalletProvider'; +import EligibilityBadges from '@/components/views/donate/common/EligibilityBadges'; +import EstimatedMatchingToast from '../../EstimatedMatchingToast'; interface QRDonationCardProps extends IDonationCardProps { qrAcceptedTokens: IProjectAcceptedToken[]; setIsQRDonation: (isQRDonation: boolean) => void; } +const decimals = 18; const formatAmountToDisplay = (amount: bigint) => { - const decimals = 18; return truncateToDecimalPlaces( formatUnits(amount, decimals), decimals / 3, @@ -62,13 +69,16 @@ export const QRDonationCard: FC<QRDonationCardProps> = ({ const { formatMessage } = useIntl(); const router = useRouter(); const { isSignedIn, isEnabled } = useAppSelector(state => state.user); - const [showDonateModal, setShowDonateModal] = useState(false); + const [_showDonateModal, setShowDonateModal] = useState(false); const { modalCallback: signInThenDonate } = useModalCallback(() => setShowDonateModal(true), ); + const { isConnected, chain } = useGeneralWallet(); const { project, + hasActiveQFRound, + activeStartedRound, setQRDonationStatus, setDraftDonationData, setPendingDonationExists, @@ -85,10 +95,10 @@ export const QRDonationCard: FC<QRDonationCardProps> = ({ retrieveDraftDonation, } = useQRCodeDonation(project); - const { addresses, id } = project; + const { addresses, id, verified } = project; const draftDonationId = Number(router.query.draft_donation!); const [amount, setAmount] = useState(0n); - const [usdAmount, setUsdAmount] = useState('0.00'); + const [usdAmount, setUsdAmount] = useState(0); const [tokenPrice, setTokenPrice] = useState(0); const stellarToken = qrAcceptedTokens.find( @@ -98,6 +108,25 @@ export const QRDonationCard: FC<QRDonationCardProps> = ({ address => address.chainType === ChainType.STELLAR, ); + const isOnEligibleNetworks = activeStartedRound?.eligibleNetworks?.includes( + config.STELLAR_NETWORK_NUMBER, + ); + const isProjectGivbacksEligible = !!verified; + const isInQF = !!isOnEligibleNetworks; + const showConnectWallet = isProjectGivbacksEligible || isInQF; + const textToDisplayOnConnect = + isProjectGivbacksEligible && isInQF + ? 'label.please_connect_your_wallet_to_win_givbacks_and_match' + : isProjectGivbacksEligible + ? 'label.please_connect_your_wallet_to_win_givbacks' + : 'label.please_connect_your_wallet_to_match'; + const donationUsdValue = + (tokenPrice || 0) * Number(ethers.utils.formatEther(amount)); + const isDonationMatched = + !!activeStartedRound && + isOnEligibleNetworks && + donationUsdValue >= (activeStartedRound?.minimumValidUsdValue || 0); + useEffect(() => { const eventSource = new EventSource( `${process.env.NEXT_PUBLIC_BASE_ROUTE}/events`, @@ -136,20 +165,42 @@ export const QRDonationCard: FC<QRDonationCardProps> = ({ }, [draftDonationId]); const goBack = async () => { + const prevQuery = router.query; + + const updateQuery = (excludeKey: string) => + Object.keys(prevQuery).reduce((acc, key) => { + return key !== excludeKey + ? { ...acc, [key]: prevQuery[key] } + : acc; + }, {}); + if (showQRCode) { const draftDonation = await checkDraftDonationStatus(draftDonationId); + if (draftDonation?.status === 'matched') { setQRDonationStatus('success'); setDraftDonationData(draftDonation); return; } + await markDraftDonationAsFailed(draftDonationId); setPendingDonationExists?.(false); setShowQRCode(false); + + await router.push( + { query: updateQuery('draft_donation') }, + undefined, + { shallow: true }, + ); } else { setIsQRDonation(false); + + await router.push({ query: updateQuery('chain') }, undefined, { + shallow: true, + }); } + setQRDonationStatus('waiting'); }; @@ -215,14 +266,6 @@ export const QRDonationCard: FC<QRDonationCardProps> = ({ } }; - const convertAmountToUSD = (amount: bigint) => { - if (!stellarToken || !tokenPrice) return '0.00'; - - const priceBigInt = BigInt(Math.floor(tokenPrice * 100)); - const amountInUsd = (amount * priceBigInt) / 100n; - return formatBalance(formatAmountToDisplay(amountInUsd)); - }; - const calculateUsdAmount = (amount?: number) => { if (!tokenPrice || !amount) return '0.00'; @@ -230,7 +273,11 @@ export const QRDonationCard: FC<QRDonationCardProps> = ({ }; useEffect(() => { - setUsdAmount(convertAmountToUSD(amount)); + const donationUsdValue = + (tokenPrice || 0) * + (truncateToDecimalPlaces(formatUnits(amount, decimals), decimals) || + 0); + setUsdAmount(donationUsdValue); }, [amount, tokenPrice]); useEffect(() => { @@ -244,6 +291,16 @@ export const QRDonationCard: FC<QRDonationCardProps> = ({ fetchTokenPrice(); }, []); + const showEstimatedMatching = + !showQRCode && + !!chain && + hasActiveQFRound && + !!activeStartedRound?.eligibleNetworks?.includes( + config.NON_EVM_NETWORKS_CONFIG[ChainType.STELLAR].networkId, + ) && + isDonationMatched && + !!amount; + return ( <> <CardHead> @@ -266,107 +323,132 @@ export const QRDonationCard: FC<QRDonationCardProps> = ({ })} /> )} - {!showQRCode && !isSignedIn && stellarToken?.isGivbackEligible && ( - <InlineToast - noIcon - type={EToastType.Hint} - message={formatMessage({ - id: 'label.sign_in_with_your_eth_wallet_for_givebacks', + {!showQRCode && !isConnected && showConnectWallet && ( + <ConnectWallet> + <IconWalletOutline24 color={neutralColors.gray[700]} /> + {formatMessage({ + id: textToDisplayOnConnect, })} - link={links.GIVBACK_DOC} - linkText={capitalizeAllWords( - formatMessage({ - id: 'label.learn_more', - }), - )} + </ConnectWallet> + )} + {!showQRCode && ( + <EligibilityBadges + amount={amount} + token={stellarToken} + tokenPrice={tokenPrice} + style={{ marginBottom: '5px' }} /> )} - {!showQRCode ? ( - <> - <StyledInputWrapper> - <SelectTokenWrapper - $alignItems='center' - $justifyContent='space-between' - > - <Flex gap='8px' $alignItems='center'> - <TokenIconWithGIVBack - showGiveBack={ - stellarToken?.isGivbackEligible - } - symbol={stellarToken?.symbol} - size={32} + <div> + {!showQRCode && ( + <EstimatedMatchingToast + projectData={project} + token={stellarToken} + amount={amount} + tokenPrice={tokenPrice} + show={showEstimatedMatching} + isStellar + /> + )} + {!showQRCode ? ( + <ForEstimatedMatchingAnimation + showEstimatedMatching={showEstimatedMatching} + > + <StyledInputWrapper> + <SelectTokenWrapper + $alignItems='center' + $justifyContent='space-between' + > + <Flex gap='8px' $alignItems='center'> + <TokenIconWithGIVBack + showGiveBack={ + stellarToken?.isGivbackEligible + } + symbol={stellarToken?.symbol} + size={32} + /> + <TokenSymbol> + { + config.NETWORKS_CONFIG[ + ChainType.STELLAR + ].name + }{' '} + ({stellarToken?.symbol}) + </TokenSymbol> + </Flex> + </SelectTokenWrapper> + <QRDonationInput> + <Input amount={amount} setAmount={setAmount} /> + <UsdAmountCard> + $ {usdAmount.toFixed(2)} + </UsdAmountCard> + </QRDonationInput> + </StyledInputWrapper> + <CardBottom> + <FlexStyled + $justifyContent='space-between' + $color={neutralColors.gray[100]} + > + <P> + {formatMessage({ id: 'label.donating_to' })}{' '} + <strong + style={{ textTransform: 'capitalize' }} + > + {project.title || '--'} + </strong> + </P> + <B>{formatAmountToDisplay(amount)}</B> + </FlexStyled> + <FlexStyled + $justifyContent='space-between' + $color={neutralColors.gray[300]} + > + <B> + {formatMessage({ + id: 'label.your_total_donation', + })} + </B> + <B>{formatAmountToDisplay(amount)}</B> + </FlexStyled> + {amount === 0n ? ( + <OutlineButton + label='Next' + color='primary' + icon={<IconArrowRight16 />} + disabled /> - <TokenSymbol> - { - config.NETWORKS_CONFIG[ - ChainType.STELLAR - ].name - }{' '} - ({stellarToken?.symbol}) - </TokenSymbol> - </Flex> - </SelectTokenWrapper> - <QRDonationInput> - <Input amount={amount} setAmount={setAmount} /> - <UsdAmountCard>$ {usdAmount}</UsdAmountCard> - </QRDonationInput> - </StyledInputWrapper> - <CardBottom> - <FlexStyled - $justifyContent='space-between' - $color={neutralColors.gray[100]} - > - <P> - {formatMessage({ id: 'label.donating_to' })}{' '} - <strong style={{ textTransform: 'capitalize' }}> - {project.title || '--'} - </strong> - </P> - <B>{formatAmountToDisplay(amount)}</B> - </FlexStyled> - <FlexStyled - $justifyContent='space-between' - $color={neutralColors.gray[300]} - > - <B> - {formatMessage({ - id: 'label.your_total_donation', - })} - </B> - <B>{formatAmountToDisplay(amount)}</B> - </FlexStyled> - <Button - label='Next' - color='primary' - icon={ - <Image - src='/images/rarrow.svg' - alt='Next' - width={16} - height={16} - style={{ marginLeft: '8px' }} // Add margin to the right of the icon + ) : ( + <Button + label='Next' + color='primary' + icon={<IconArrowRight16 />} + onClick={handleNext} /> - } - onClick={handleNext} - disabled={amount === 0n} - /> - </CardBottom> - </> - ) : ( - <QRDonationCardContent - tokenData={stellarToken} - usdAmount={calculateUsdAmount(draftDonationData?.amount)} - amount={draftDonationData?.amount?.toString() ?? '0.00'} - qrDonationStatus={qrDonationStatus} - draftDonationData={draftDonationData} - projectAddress={projectAddress} - draftDonationLoading={draftDonationLoading} - /> - )} + )} + </CardBottom> + </ForEstimatedMatchingAnimation> + ) : ( + <QRDonationCardContent + tokenData={stellarToken} + usdAmount={calculateUsdAmount( + draftDonationData?.amount, + )} + amount={draftDonationData?.amount?.toString() ?? '0.00'} + qrDonationStatus={qrDonationStatus} + draftDonationData={draftDonationData} + projectAddress={projectAddress} + draftDonationLoading={draftDonationLoading} + /> + )} + </div> </> ); }; +const ConnectWallet = styled(BadgesBase)` + margin-bottom: 5px; +`; + const CardHead = styled(Flex)` align-items: center; padding: 1rem 0; @@ -387,13 +469,14 @@ const TokenSymbol = styled(B)` white-space: nowrap; `; -export const UsdAmountCard = styled.div` - padding: 4px 16px; - margin-inline: 4px; +export const UsdAmountCard = styled(SublineBold)` + padding: 2px 8px; white-space: nowrap; background: ${neutralColors.gray[300]}; - border-radius: 16px; - color: ${neutralColors.gray[700]}; + border-radius: 4px; + color: ${neutralColors.gray[700]} !important; + display: flex; + align-items: center; `; const CardBottom = styled.div` @@ -431,7 +514,7 @@ const Input = styled(AmountInput)` const QRDonationInput = styled(Flex)` width: 100%; border-top: 2px solid ${neutralColors.gray[300]}; - + padding-right: 8px; ${mediaQueries.tablet} { border-left: 2px solid ${neutralColors.gray[300]}; border-top: none; @@ -440,7 +523,7 @@ const QRDonationInput = styled(Flex)` const StyledInputWrapper = styled(InputWrapper)` flex-direction: column; - + background-color: white; ${mediaQueries.tablet} { flex-direction: row; } diff --git a/src/components/views/donate/OnTime/SelectTokenModal/QRCodeDonation/QRDonationCardContent.tsx b/src/components/views/donate/OneTime/SelectTokenModal/QRCodeDonation/QRDonationCardContent.tsx similarity index 100% rename from src/components/views/donate/OnTime/SelectTokenModal/QRCodeDonation/QRDonationCardContent.tsx rename to src/components/views/donate/OneTime/SelectTokenModal/QRCodeDonation/QRDonationCardContent.tsx diff --git a/src/components/views/donate/OnTime/SelectTokenModal/QRCodeDonation/QRDonationDetails.tsx b/src/components/views/donate/OneTime/SelectTokenModal/QRCodeDonation/QRDonationDetails.tsx similarity index 100% rename from src/components/views/donate/OnTime/SelectTokenModal/QRCodeDonation/QRDonationDetails.tsx rename to src/components/views/donate/OneTime/SelectTokenModal/QRCodeDonation/QRDonationDetails.tsx diff --git a/src/components/views/donate/OnTime/SelectTokenModal/SelectTokenModal.tsx b/src/components/views/donate/OneTime/SelectTokenModal/SelectTokenModal.tsx similarity index 92% rename from src/components/views/donate/OnTime/SelectTokenModal/SelectTokenModal.tsx rename to src/components/views/donate/OneTime/SelectTokenModal/SelectTokenModal.tsx index 010c532dbe..00a154a276 100644 --- a/src/components/views/donate/OnTime/SelectTokenModal/SelectTokenModal.tsx +++ b/src/components/views/donate/OneTime/SelectTokenModal/SelectTokenModal.tsx @@ -25,7 +25,8 @@ import { shortenAddress, showToastError } from '@/lib/helpers'; import { useGeneralWallet } from '@/providers/generalWalletProvider'; import { wagmiConfig } from '@/wagmiConfigs'; import { ChainType } from '@/types/config'; -import { getBalanceForToken } from './getBalanceForToken'; +import { getBalanceForToken } from './services'; +import { fetchTokenBalances } from '@/services/token'; import { Spinner } from '@/components/Spinner'; export interface ISelectTokenModalProps extends IModal { @@ -83,7 +84,7 @@ const SelectTokenInnerModal: FC<ISelectTokenModalProps> = ({ >(undefined); const { setSelectedOneTimeToken } = useDonateData(); const { walletAddress, isOnEVM, isConnected } = useGeneralWallet(); - const { chain: evmChain, address } = useAccount(); + const { chain: evmChain } = useAccount(); const [balanceIsLoading, setBalanceIsLoading] = useState<boolean>(false); useEffect(() => { @@ -132,7 +133,6 @@ const SelectTokenInnerModal: FC<ISelectTokenModalProps> = ({ ], }) .then(results => { - console.log('results', results); const _customTokenData = { ...initialToken, address: searchQuery, @@ -177,21 +177,14 @@ const SelectTokenInnerModal: FC<ISelectTokenModalProps> = ({ }, [customToken, walletAddress]); useEffect(() => { - const fetchTokenBalances = async () => { + const fetchBalances = async () => { try { setBalanceIsLoading(true); - const balances = await Promise.all( - filteredTokens.map(async token => { - const isEvm = token?.chainType === ChainType.EVM; - return isEvm - ? { - token, - balance: await getBalanceForToken( - token, - walletAddress, - ), - } - : { + const balances = isOnEVM + ? await fetchTokenBalances(filteredTokens, walletAddress) + : await Promise.all( + filteredTokens.map(async token => { + return { token, balance: await getBalanceForToken( token, @@ -199,18 +192,25 @@ const SelectTokenInnerModal: FC<ISelectTokenModalProps> = ({ connection, ), }; - }), - ); + }), + ); setTokenBalances(balances); setBalanceIsLoading(true); } catch (error) { - console.error('Error fetching token balances:', error); + console.error('error on fetchTokenBalances', { error }); } }; if (isConnected) { - fetchTokenBalances(); + fetchBalances(); } - }, [tokens, filteredTokens, walletAddress]); + }, [ + tokens, + connection, + filteredTokens, + isConnected, + isOnEVM, + walletAddress, + ]); // Sort tokens by balance const sortedTokens = tokenBalances.sort( diff --git a/src/components/views/donate/OnTime/SelectTokenModal/TokenInfo.tsx b/src/components/views/donate/OneTime/SelectTokenModal/TokenInfo.tsx similarity index 100% rename from src/components/views/donate/OnTime/SelectTokenModal/TokenInfo.tsx rename to src/components/views/donate/OneTime/SelectTokenModal/TokenInfo.tsx diff --git a/src/components/views/donate/OnTime/SelectTokenModal/getBalanceForToken.tsx b/src/components/views/donate/OneTime/SelectTokenModal/services.tsx similarity index 100% rename from src/components/views/donate/OnTime/SelectTokenModal/getBalanceForToken.tsx rename to src/components/views/donate/OneTime/SelectTokenModal/services.tsx diff --git a/src/components/views/donate/OnTime/TotalDonation.tsx b/src/components/views/donate/OneTime/TotalDonation.tsx similarity index 82% rename from src/components/views/donate/OnTime/TotalDonation.tsx rename to src/components/views/donate/OneTime/TotalDonation.tsx index 568313347d..8e976ea73c 100644 --- a/src/components/views/donate/OnTime/TotalDonation.tsx +++ b/src/components/views/donate/OneTime/TotalDonation.tsx @@ -3,7 +3,7 @@ import { Caption, neutralColors, Flex } from '@giveth/ui-design-system'; import { FC } from 'react'; import { useIntl } from 'react-intl'; import { formatPrice } from '@/lib/helpers'; -import { calcDonationShare } from '@/components/views/donate/helpers'; +import { calcDonationShare } from '@/components/views/donate/common/helpers'; import { IProjectAcceptedToken } from '@/apollo/types/gqlTypes'; interface ITotalDonation { @@ -44,11 +44,11 @@ const TotalDonation: FC<ITotalDonation> = props => { {formatMessage({ id: 'label.donating_to' })} <b>{' ' + titleSummary(projectTitle)}</b> </Caption> - {isActive && ( - <Caption> - {formatPrice(projectDonation) + ' ' + symbol} - </Caption> - )} + <Caption> + {isActive + ? formatPrice(projectDonation) + ' ' + symbol + : '---'} + </Caption> </TableRow> <TableRow> <Caption> @@ -57,23 +57,23 @@ const TotalDonation: FC<ITotalDonation> = props => { {formatMessage({ id: 'label.to_lowercase' })} <b> Giveth</b> </Caption> - {isActive && ( - <Caption> - {formatPrice(givethDonation) + ' ' + symbol} - </Caption> - )} + <Caption> + {isActive + ? formatPrice(givethDonation) + ' ' + symbol + : '---'} + </Caption> </TableRow> <Total> <Caption $medium> {formatMessage({ id: 'label.your_total_donation' })} </Caption> - {isActive && ( - <Caption $medium> - {formatPrice(projectDonation + givethDonation) + + <Caption $medium> + {isActive + ? formatPrice(projectDonation + givethDonation) + ' ' + - symbol} - </Caption> - )} + symbol + : '---'} + </Caption> </Total> </Container> ); diff --git a/src/components/views/donate/QFEligibleNetworks.tsx b/src/components/views/donate/QFEligibleNetworks.tsx new file mode 100644 index 0000000000..4ca6f3e6ab --- /dev/null +++ b/src/components/views/donate/QFEligibleNetworks.tsx @@ -0,0 +1,130 @@ +import styled from 'styled-components'; +import { + brandColors, + Caption, + IconExternalLink24, + IconNetwork24, + neutralColors, + OutlineButton, + SublineBold, +} from '@giveth/ui-design-system'; +import { useIntl } from 'react-intl'; +import React, { useState } from 'react'; +import { useRouter } from 'next/router'; +import ExternalLink from '@/components/ExternalLink'; +import links from '@/lib/constants/links'; +import SwitchNetwork from '@/components/modals/SwitchNetwork'; +import { useDonateData } from '@/context/donate.context'; +import { ChainType } from '@/types/config'; +import config from '@/configuration'; +import { IconWithTooltip } from '@/components/IconWithToolTip'; +import { useGeneralWallet } from '@/providers/generalWalletProvider'; + +const QFEligibleNetworks = () => { + const [showModal, setShowModal] = useState(false); + const { isConnected } = useGeneralWallet(); + const { formatMessage } = useIntl(); + const { activeStartedRound } = useDonateData(); + const router = useRouter(); + const isQRDonation = router.query.chain === ChainType.STELLAR.toLowerCase(); + const eligibleNetworksWithoutStellar = activeStartedRound?.eligibleNetworks + .filter(network => network !== config.STELLAR_NETWORK_NUMBER) + .map(network => ({ + networkId: network, + chainType: config.EVM_NETWORKS_CONFIG[network] + ? ChainType.EVM + : ChainType.SOLANA, + })); + if (!activeStartedRound) return null; + return ( + <Wrapper> + <Caption $medium> + {formatMessage({ id: 'label.eligible_networks_for_matching' })} + </Caption> + <IconsWrapper> + {activeStartedRound?.eligibleNetworks?.map(network => ( + <IconWithTooltip + icon={ + <TooltipIconWrapper> + {config.NETWORKS_CONFIG_WITH_ID[ + network + ]?.chainLogo(24)} + </TooltipIconWrapper> + } + direction='top' + align='top' + key={network} + > + <SublineBold> + {config.NETWORKS_CONFIG_WITH_ID[network]?.name} + </SublineBold> + </IconWithTooltip> + ))} + </IconsWrapper> + {!isQRDonation && isConnected && ( + <ButtonsWrapper> + <OutlineButton + onClick={() => setShowModal(true)} + size='medium' + icon={<IconNetwork24 />} + label={formatMessage({ id: 'label.switch_network' })} + /> + <ExternalLink href={links.ACROSS_BRIDGE}> + <OutlineButton + size='medium' + icon={<IconExternalLink24 />} + label={formatMessage({ id: 'label.bridge_tokens' })} + /> + </ExternalLink> + </ButtonsWrapper> + )} + {showModal && ( + <SwitchNetwork + setShowModal={setShowModal} + customNetworks={eligibleNetworksWithoutStellar} + /> + )} + </Wrapper> + ); +}; + +const TooltipIconWrapper = styled.div` + margin-top: 4px; +`; + +const IconsWrapper = styled.div` + margin-top: 14px; + display: flex; + gap: 4px; + img { + filter: grayscale(100%); + opacity: 0.4; + transition: all 0.3s; + &:hover { + filter: grayscale(0); + opacity: 1; + } + } +`; + +const ButtonsWrapper = styled.div` + margin-top: 16px; + display: flex; + gap: 16px; + button { + height: 32px; + color: ${brandColors.giv[500]}; + border: 1px solid ${brandColors.giv[500]}; + } +`; + +const Wrapper = styled.div` + margin-bottom: 32px; + border-radius: 8px; + border: 1px solid ${neutralColors.gray[300]}; + background: ${neutralColors.gray[100]}; + padding: 16px; + color: ${neutralColors.gray[800]}; +`; + +export default QFEligibleNetworks; diff --git a/src/components/views/donate/Recurring/RecurringDonationCard.tsx b/src/components/views/donate/Recurring/RecurringDonationCard.tsx index 4a13b307cc..d40b596581 100644 --- a/src/components/views/donate/Recurring/RecurringDonationCard.tsx +++ b/src/components/views/donate/Recurring/RecurringDonationCard.tsx @@ -1,19 +1,18 @@ import { B, + brandColors, Button, Caption, - GLink, + Flex, H6, IconCaretDown16, IconChevronRight16, IconHelpFilled16, IconPlus16, IconRefresh16, - P, - brandColors, neutralColors, + P, semanticColors, - Flex, } from '@giveth/ui-design-system'; import React, { useEffect, useMemo, useState } from 'react'; import styled from 'styled-components'; @@ -46,8 +45,6 @@ import config from '@/configuration'; import { WrongNetworkLayer } from '../WrongNetworkLayer'; import { ModifySuperTokenModal } from './ModifySuperToken/ModifySuperTokenModal'; import { limitFraction } from '@/helpers/number'; -import CheckBox from '@/components/Checkbox'; -import { CheckBoxContainer } from '../OnTime/OneTimeDonationCard'; import AlloProtocolFirstDonationModal from './AlloProtocolFirstDonationModal'; import links from '@/lib/constants/links'; import Routes from '@/lib/constants/Routes'; @@ -55,8 +52,19 @@ import { useModalCallback } from '@/hooks/useModalCallback'; import { useAppSelector } from '@/features/hooks'; import { findAnchorContractAddress } from '@/helpers/superfluid'; import GIVBackToast from '../GIVBackToast'; +import { useGeneralWallet } from '@/providers/generalWalletProvider'; -// These two functions are used to make the slider more user friendly by mapping the slider's value to a new range. +import { + GLinkStyled, + IconWrapper, + Input, + InputWrapper, + SelectTokenPlaceHolder, + SelectTokenWrapper, +} from '@/components/views/donate/common/common.styled'; +import DonateAnonymously from '@/components/views/donate/common/DonateAnonymously'; + +// These two functions are used to make the slider more user-friendly by mapping the slider's value to a new range. /** * The mapValue function takes a value from the slider (0 to 100) and maps it to a new range. * If the slider value is between 0 and 90, it maps it to a range of 0 to 50. @@ -115,6 +123,8 @@ export const RecurringDonationCard = () => { setShowAlloProtocolModal(true), ); + const { isConnected } = useGeneralWallet(); + const { data: balance, refetch, @@ -278,6 +288,7 @@ export const RecurringDonationCard = () => { $alignItems='center' $justifyContent='space-between' onClick={() => setShowSelectTokenModal(true)} + disabled={!isConnected} > {selectedRecurringToken ? ( <Flex gap='8px' $alignItems='center'> @@ -370,7 +381,7 @@ export const RecurringDonationCard = () => { })} </Caption> <Flex gap='16px' $alignItems='center'> - <StyledSlider + <Slider min={0} max={100} step={0.1} @@ -605,8 +616,12 @@ export const RecurringDonationCard = () => { setDonationToGiveth={e => { setDonationToGiveth(e); }} + disabled={!selectedRecurringToken} donationToGiveth={donationToGiveth} - title='Add a recurring donation to Giveth' + title={ + formatMessage({ id: 'label.donate_to' }) + + ' Giveth' + } /> </GivethSection> )} @@ -726,21 +741,11 @@ export const RecurringDonationCard = () => { alt='Superfluid logo' /> </Flex> - <CheckBoxContainer> - <CheckBox - label={formatMessage({ - id: 'label.make_it_anonymous', - })} - checked={anonymous} - onChange={() => setAnonymous(!anonymous)} - size={14} - /> - <div> - {formatMessage({ - id: 'component.tooltip.donate_anonymously', - })} - </div> - </CheckBoxContainer> + <DonateAnonymously + anonymous={anonymous} + setAnonymous={setAnonymous} + selectedToken={selectedRecurringToken} + /> {showSelectTokenModal && ( <SelectTokenModal setShowModal={setShowSelectTokenModal} /> )} @@ -809,39 +814,6 @@ const RecurringSection = styled(Flex)` text-align: left; `; -export const SelectTokenWrapper = styled(Flex)` - cursor: pointer; - gap: 16px; -`; - -export const SelectTokenPlaceHolder = styled(B)` - white-space: nowrap; -`; - -export const InputWrapper = styled(Flex)` - border: 2px solid ${neutralColors.gray[300]}; - border-radius: 8px; - & > * { - padding: 13px 16px; - } - align-items: center; -`; - -export const Input = styled(AmountInput)` - width: 100%; - border-left: 2px solid ${neutralColors.gray[300]}; - #amount-input { - border: none; - flex: 1; - font-family: Red Hat Text; - font-size: 16px; - font-style: normal; - font-weight: 500; - line-height: 150%; /* 24px */ - width: 100%; - } -`; - const RecurringMessage = styled(P)` font-size: 12px; font-style: normal; @@ -850,20 +822,6 @@ const RecurringMessage = styled(P)` color: #e6492d; `; -export const IconWrapper = styled.div` - cursor: pointer; - color: ${brandColors.giv[500]}; -`; - -export const GLinkStyled = styled(GLink)` - &&:hover { - cursor: pointer; - text-decoration: underline; - } -`; - -const StyledSlider = styled(Slider)``; - const InputSlider = styled(AmountInput)` width: 27%; border: 2px solid ${neutralColors.gray[300]}; diff --git a/src/components/views/donate/SuccessView.tsx b/src/components/views/donate/SuccessView.tsx index 4b5942fe5d..6e3d9eae1c 100644 --- a/src/components/views/donate/SuccessView.tsx +++ b/src/components/views/donate/SuccessView.tsx @@ -36,7 +36,10 @@ import { DonationInfo } from './DonationInfo'; import { ManageRecurringDonation } from './Recurring/ManageRecurringDonation'; import EndaomentProjectsInfo from '../project/EndaomentProjectsInfo'; -export const SuccessView: FC = () => { +interface ISuccessView { + isStellar?: boolean; +} +export const SuccessView: FC<ISuccessView> = ({ isStellar }) => { const { formatMessage } = useIntl(); const { successDonation, hasActiveQFRound, project } = useDonateData(); const { @@ -71,8 +74,9 @@ export const SuccessView: FC = () => { const { activeStartedRound } = getActiveRound(project.qfRounds); - const isOnEligibleNetworks = - chainId && activeStartedRound?.eligibleNetworks?.includes(chainId); + const isOnEligibleNetworks = activeStartedRound?.eligibleNetworks?.includes( + (isStellar ? config.STELLAR_NETWORK_NUMBER : chainId) || 0, + ); useEffect(() => { if (!hasMultipleTxs) return; diff --git a/src/components/views/donate/SwitchToAcceptedChain.tsx b/src/components/views/donate/SwitchToAcceptedChain.tsx index 4c1c3de87e..ca7bea5f0a 100644 --- a/src/components/views/donate/SwitchToAcceptedChain.tsx +++ b/src/components/views/donate/SwitchToAcceptedChain.tsx @@ -1,15 +1,19 @@ -import React, { FC } from 'react'; +import React, { FC, useEffect, useState } from 'react'; import { useIntl } from 'react-intl'; -import { Caption } from '@giveth/ui-design-system'; -import { Chain } from 'viem'; -import { getNetworkNames } from '@/components/views/donate/helpers'; import { - NetworkToast, - SwitchCaption, -} from '@/components/views/donate/common.styled'; -import { INetworkIdWithChain } from './common.types'; // Import the type + brandColors, + FlexCenter, + IconWrongNetwork24, + neutralColors, + semanticColors, + SublineBold, +} from '@giveth/ui-design-system'; +import { Chain } from 'viem'; +import styled from 'styled-components'; +import { INetworkIdWithChain } from './common/common.types'; // Import the type import { useGeneralWallet } from '@/providers/generalWalletProvider'; import { ChainType } from '@/types/config'; +import config from '@/configuration'; interface ISwitchToAcceptedChain { acceptedChains: INetworkIdWithChain[]; @@ -22,10 +26,18 @@ const SwitchToAcceptedChain: FC<ISwitchToAcceptedChain> = ({ }) => { const { formatMessage } = useIntl(); const { chain, walletChainType } = useGeneralWallet(); + const [show, setShow] = useState(false); + + const networkId = (chain as Chain)?.id || config.SOLANA_CONFIG.networkId; + const networkName = config.NETWORKS_CONFIG_WITH_ID[networkId]?.name; - const networkId = (chain as Chain)?.id; + useEffect(() => { + // To prevent SwitchToAcceptedChain flickering + setTimeout(() => setShow(true), 1000); + }, []); if ( + !show || !acceptedChains || acceptedChains.some( chain => @@ -37,24 +49,43 @@ const SwitchToAcceptedChain: FC<ISwitchToAcceptedChain> = ({ return null; } - // Assuming getNetworkNames is updated to handle INetworkIdWithChain array return ( <NetworkToast> - <Caption $medium> - {formatMessage({ - id: 'label.this_project_only_accept_on', - })}{' '} - {getNetworkNames(acceptedChains, 'and')}. - </Caption> - <SwitchCaption + <FlexCenter gap='4px'> + <IconWrongNetwork24 color={semanticColors.punch[500]} /> + <SublineBold> + {formatMessage({ + id: 'label.this_project_doesnt_accept_on', + })} + {' ' + networkName} + </SublineBold> + </FlexCenter> + <SublineBoldStyled onClick={() => { setShowChangeNetworkModal(true); }} > - {formatMessage({ id: 'label.switch_network' })} - </SwitchCaption> + {formatMessage({ id: 'label.switch_to_supported' })} + </SublineBoldStyled> </NetworkToast> ); }; +const SublineBoldStyled = styled(SublineBold)` + cursor: pointer; + color: ${brandColors.giv[500]}; +`; + +const NetworkToast = styled.div` + display: flex; + margin: 12px 0 24px; + gap: 10px; + justify-content: space-between; + align-items: center; + padding: 4px 8px; + border-radius: 8px; + border: 1px solid ${semanticColors.punch[200]}; + color: ${neutralColors.gray[800]}; +`; + export default SwitchToAcceptedChain; diff --git a/src/components/views/donate/common.styled.ts b/src/components/views/donate/common.styled.ts deleted file mode 100644 index 5a3339bbf6..0000000000 --- a/src/components/views/donate/common.styled.ts +++ /dev/null @@ -1,29 +0,0 @@ -import styled from 'styled-components'; -import { - brandColors, - Caption, - neutralColors, - Flex, -} from '@giveth/ui-design-system'; - -export const NetworkToast = styled(Flex)` - gap: 10px; - width: 100%; - margin-bottom: 9px; - color: ${neutralColors.gray[800]}; - > :last-child { - flex-shrink: 0; - } - > div:first-child > svg { - flex-shrink: 0; - } - img { - padding-right: 12px; - } -`; - -export const SwitchCaption = styled(Caption)` - color: ${brandColors.pinky[500]}; - cursor: pointer; - margin: 0 auto; -`; diff --git a/src/components/views/donate/common/DonateAnonymously.tsx b/src/components/views/donate/common/DonateAnonymously.tsx new file mode 100644 index 0000000000..c61adf16b0 --- /dev/null +++ b/src/components/views/donate/common/DonateAnonymously.tsx @@ -0,0 +1,62 @@ +import React, { FC } from 'react'; +import styled from 'styled-components'; +import { neutralColors } from '@giveth/ui-design-system'; +import { useIntl } from 'react-intl'; +import ToggleSwitch, { + EToggleSwitchSizes, + EToggleSwitchThemes, +} from '@/components/ToggleSwitch'; +import { useGeneralWallet } from '@/providers/generalWalletProvider'; +import { IProjectAcceptedToken } from '@/apollo/types/gqlTypes'; +import { ISelectTokenWithBalance } from '@/context/donate.context'; + +interface IDonateAnonymously { + anonymous: boolean; + setAnonymous: (anonymous: boolean) => void; + selectedToken?: IProjectAcceptedToken | ISelectTokenWithBalance; +} + +const DonateAnonymously: FC<IDonateAnonymously> = props => { + const { anonymous, setAnonymous, selectedToken } = props; + const { formatMessage } = useIntl(); + const { isConnected } = useGeneralWallet(); + return ( + <CheckBoxContainer> + <ToggleSwitch + isOn={anonymous} + toggleOnOff={setAnonymous} + size={EToggleSwitchSizes.SMALL} + theme={EToggleSwitchThemes.PURPLE_GRAY} + label={formatMessage({ + id: 'label.make_it_anonymous', + })} + disabled={!isConnected || !selectedToken} + style={{ marginLeft: '-14px' }} + /> + <Caption disabled={!isConnected || !selectedToken}> + {formatMessage({ + id: 'component.tooltip.donate_anonymously', + })} + </Caption> + </CheckBoxContainer> + ); +}; + +const CheckBoxContainer = styled.div` + margin-top: 24px; + border-radius: 8px; + border: 1px solid ${neutralColors.gray[300]}; + padding: 16px; + > div:nth-child(2) { + color: ${neutralColors.gray[900]}; + font-size: 12px; + margin-top: 9px; + } +`; + +const Caption = styled.div<{ disabled: boolean }>` + color: ${props => + props.disabled ? neutralColors.gray[600] + ' !important' : 'inherit'}; +`; + +export default DonateAnonymously; diff --git a/src/components/views/donate/common/EligibilityBadges.tsx b/src/components/views/donate/common/EligibilityBadges.tsx new file mode 100644 index 0000000000..17a59877e1 --- /dev/null +++ b/src/components/views/donate/common/EligibilityBadges.tsx @@ -0,0 +1,134 @@ +import { + IconGIVBack24, + IconNoGiveback24, + IconQFNew, + IconQFNotEligible24, + neutralColors, + semanticColors, +} from '@giveth/ui-design-system'; +import React, { CSSProperties, FC } from 'react'; +import { useIntl } from 'react-intl'; +import { Chain, formatUnits } from 'viem'; +import { useRouter } from 'next/router'; +import { + BadgesBase, + EligibilityBadgeWrapper, +} from '@/components/views/donate/common/common.styled'; +import { GIVBACKS_DONATION_QUALIFICATION_VALUE_USD } from '@/lib/constants/constants'; +import { useGeneralWallet } from '@/providers/generalWalletProvider'; +import { useDonateData } from '@/context/donate.context'; +import { IProjectAcceptedToken } from '@/apollo/types/gqlTypes'; +import config from '@/configuration'; +import { ChainType } from '@/types/config'; +import { useAppSelector } from '@/features/hooks'; +import { truncateToDecimalPlaces } from '@/lib/helpers'; + +interface IEligibilityBadges { + tokenPrice?: number; + token?: IProjectAcceptedToken; + amount: bigint; + style?: CSSProperties; +} + +const EligibilityBadges: FC<IEligibilityBadges> = props => { + const { tokenPrice, amount, token, style } = props; + const { activeQFRound } = useAppSelector(state => state.general); + const { isConnected, chain } = useGeneralWallet(); + const { activeStartedRound, project } = useDonateData(); + const { formatMessage } = useIntl(); + const { verified } = project || {}; + const router = useRouter(); + const isStellar = router.query.chain === ChainType.STELLAR.toLowerCase(); + const isTokenGivbacksEligible = token?.isGivbackEligible; + const isProjectGivbacksEligible = !!verified; + const networkId = isStellar + ? config.STELLAR_NETWORK_NUMBER + : (chain as Chain)?.id + ? (chain as Chain)?.id + : config.SOLANA_CONFIG.networkId; + const isOnQFEligibleNetworks = + activeStartedRound?.eligibleNetworks?.includes(networkId || 0); + const decimals = isStellar ? 18 : token?.decimals || 18; + + const donationUsdValue = + (tokenPrice || 0) * + (truncateToDecimalPlaces(formatUnits(amount, decimals), decimals) || 0); + + const qfEligibleWarning = !activeStartedRound || !isOnQFEligibleNetworks; + const isDonationMatched = + !!activeStartedRound && + isOnQFEligibleNetworks && + donationUsdValue >= (activeStartedRound?.minimumValidUsdValue || 0); + const givbacksEligibleWarning = + (token && !isTokenGivbacksEligible) || !isProjectGivbacksEligible; + const isGivbacksEligible = + isTokenGivbacksEligible && + isProjectGivbacksEligible && + donationUsdValue >= GIVBACKS_DONATION_QUALIFICATION_VALUE_USD; + + return isConnected ? ( + <EligibilityBadgeWrapper style={style}> + {activeQFRound && ( + <BadgesBase + warning={qfEligibleWarning} + active={isDonationMatched} + > + {!qfEligibleWarning ? ( + <IconQFNew size={30} /> + ) : ( + <IconQFNotEligible24 /> + )} + {formatMessage( + { + id: isDonationMatched + ? 'page.donate.donations_will_be_matched' + : !activeStartedRound + ? 'page.donate.project_not_eligible_for_qf' + : !isOnQFEligibleNetworks + ? 'page.donate.network_not_eligible_for_qf' + : 'page.donate.unlocks_matching_funds', + }, + { + value: activeStartedRound?.minimumValidUsdValue, + network: + config.NETWORKS_CONFIG_WITH_ID[networkId]?.name, + }, + )} + </BadgesBase> + )} + <BadgesBase + warning={givbacksEligibleWarning} + active={isGivbacksEligible} + > + {!givbacksEligibleWarning ? ( + <IconGIVBack24 + color={ + isGivbacksEligible + ? semanticColors.jade[500] + : neutralColors.gray[700] + } + /> + ) : ( + <IconNoGiveback24 /> + )} + {formatMessage( + { + id: isGivbacksEligible + ? 'page.donate.givbacks_eligible' + : !isProjectGivbacksEligible + ? 'page.donate.project_not_givbacks_eligible' + : token && !isTokenGivbacksEligible + ? 'page.donate.token_not_givbacks_eligible' + : 'page.donate.makes_you_eligible_for_givbacks', + }, + { + value: GIVBACKS_DONATION_QUALIFICATION_VALUE_USD, + token: token?.symbol, + }, + )} + </BadgesBase> + </EligibilityBadgeWrapper> + ) : null; +}; + +export default EligibilityBadges; diff --git a/src/components/views/donate/common/common.styled.ts b/src/components/views/donate/common/common.styled.ts new file mode 100644 index 0000000000..1c82abb47c --- /dev/null +++ b/src/components/views/donate/common/common.styled.ts @@ -0,0 +1,131 @@ +import styled from 'styled-components'; +import { + B, + brandColors, + Caption, + Flex, + FlexCenter, + GLink, + mediaQueries, + neutralColors, + semanticColors, +} from '@giveth/ui-design-system'; +import { AmountInput } from '@/components/AmountInput/AmountInput'; + +export const NetworkToast = styled(Flex)` + gap: 10px; + width: 100%; + margin-bottom: 9px; + color: ${neutralColors.gray[800]}; + > :last-child { + flex-shrink: 0; + } + > div:first-child > svg { + flex-shrink: 0; + } + img { + padding-right: 12px; + } +`; + +export const SwitchCaption = styled(Caption)` + color: ${brandColors.pinky[500]}; + cursor: pointer; + margin: 0 auto; +`; + +export const BadgesBase = styled(FlexCenter)<{ + active?: boolean; + warning?: boolean; +}>` + gap: 8px; + font-size: 12px; + font-weight: 500; + background: ${neutralColors.gray[200]}; + color: ${props => + props.active ? semanticColors.jade[500] : neutralColors.gray[700]}; + transition: color 0.5s ease; + border-radius: 8px; + border: 1px solid + ${props => + props.active + ? semanticColors.jade[400] + : props.warning + ? semanticColors.golden[400] + : neutralColors.gray[400]}; + padding: 4px 8px 4px 4px; +`; + +export const EligibilityBadgeWrapper = styled(Flex)` + gap: 16px; + justify-content: center; + flex-direction: column; + > div { + height: 36px; + } + ${mediaQueries.tablet} { + flex-direction: row; + justify-content: flex-start; + } +`; + +export const IconWrapper = styled.div` + cursor: pointer; + color: ${brandColors.giv[500]}; +`; + +export const GLinkStyled = styled(GLink)` + &&:hover { + cursor: pointer; + text-decoration: underline; + } +`; + +export const Input = styled(AmountInput)<{ disabled?: boolean }>` + background-color: ${props => + props.disabled ? neutralColors.gray[300] : 'white'}; + opacity: ${props => (props.disabled ? 0.4 : 1)}; + width: 100%; + border-left: 2px solid ${neutralColors.gray[300]}; + border-radius: 0 8px 8px 0; + #amount-input { + border: none; + flex: 1; + font-family: Red Hat Text; + font-size: 16px; + font-style: normal; + font-weight: 500; + line-height: 150%; /* 24px */ + width: 100%; + } +`; + +export const SelectTokenWrapper = styled(Flex)<{ disabled?: boolean }>` + cursor: ${({ disabled }) => (disabled ? 'default' : 'pointer')}; + background-color: white; + border-radius: 8px; + gap: 16px; +`; + +export const SelectTokenPlaceHolder = styled(B)` + white-space: nowrap; +`; + +export const InputWrapper = styled(Flex)` + border: 2px solid ${neutralColors.gray[300]}; + border-radius: 8px; + background-color: white; + & > * { + padding: 13px 16px; + } + align-items: center; + position: relative; +`; + +export const ForEstimatedMatchingAnimation = styled.div<{ + showEstimatedMatching?: boolean; +}>` + transform: ${props => + props.showEstimatedMatching ? 'none' : 'translateY(-36px)'}; + transition: transform 0.5s ease; +`; diff --git a/src/components/views/donate/common.types.tsx b/src/components/views/donate/common/common.types.tsx similarity index 100% rename from src/components/views/donate/common.types.tsx rename to src/components/views/donate/common/common.types.tsx diff --git a/src/components/views/donate/helpers.tsx b/src/components/views/donate/common/helpers.tsx similarity index 78% rename from src/components/views/donate/helpers.tsx rename to src/components/views/donate/common/helpers.tsx index 84be6cab74..41c7da7bd2 100644 --- a/src/components/views/donate/helpers.tsx +++ b/src/components/views/donate/common/helpers.tsx @@ -2,8 +2,6 @@ import { parseUnits } from 'viem'; import { IProjectAcceptedToken } from '@/apollo/types/gqlTypes'; import { MAX_TOKEN_ORDER } from '@/lib/constants/tokens'; import { EDonationFailedType } from '@/components/modals/FailedDonation'; -import { INetworkIdWithChain } from './common.types'; -import { getChainName } from '@/lib/network'; import { formatCrypto } from '@/helpers/number'; export const prepareTokenList = (tokens: IProjectAcceptedToken[]) => { @@ -21,24 +19,6 @@ export const prepareTokenList = (tokens: IProjectAcceptedToken[]) => { return _tokens; }; -export const getNetworkNames = ( - networks: INetworkIdWithChain[], - text: string, -) => { - return networks.map((network, index) => { - // Access the network name using networkId or chainType based on the chainType - const name = getChainName(network.networkId, network.chainType); - - const lastLoop = networks.length === index + 1; - return ( - <span key={network.networkId}> - {name} - {!lastLoop && ' ' + text + ' '} - </span> - ); - }); -}; - export interface ICreateDonation { walletAddress: string; projectId: number; @@ -62,7 +42,10 @@ export const calcDonationShare = ( totalDonation: bigint, givethDonationPercent: number, decimals = 18, -) => { +): { + projectDonation: number; + givethDonation: number; +} => { let givethDonation = (totalDonation * BigInt(givethDonationPercent)) / 100n; const minDonationAmount = parseUnits('1', decimals - decimals / 3); if (givethDonation < minDonationAmount && givethDonationPercent !== 0) { @@ -80,7 +63,6 @@ export const calcDonationShare = ( } return { projectDonation: formatCrypto(projectDonation, decimals), - givethDonation: formatCrypto(givethDonation, decimals), }; }; diff --git a/src/components/views/homepage/AnnouncementBanner.tsx b/src/components/views/homepage/AnnouncementBanner.tsx index 194f6c39fe..2831df565f 100644 --- a/src/components/views/homepage/AnnouncementBanner.tsx +++ b/src/components/views/homepage/AnnouncementBanner.tsx @@ -2,28 +2,21 @@ import styled from 'styled-components'; import Image from 'next/image'; import { brandColors, FlexCenter } from '@giveth/ui-design-system'; import ExternalLink from '@/components/ExternalLink'; -import gitcoin from '/public/images/gitcoin-grants.png'; const AnnouncementBanner = () => { return ( <Wrapper> <PStyled> <> - Donate to Giveth in Gitcoin Grants 21! We are participating - in 4 QF rounds on Gitcoin. + Have you donated on Giveth recently? Take 30 seconds and + fill out the </> - <ImageStyled - src={gitcoin} - alt='Gitcoin Grants 21' - width={20} - height={20} - /> <div id='announcement-banner'> - <ExternalLink href='https://x.com/Giveth/status/1823057210643296578'> - <Purple>Find links to all the rounds</Purple> + <ExternalLink href='https://giveth.typeform.com/donorsurvey2024'> + <Purple>2024 Donor Survey</Purple> </ExternalLink> </div> - <>and consider making a donation to support our work.</> + <>to help us improve the Giveth platform.</> </PStyled> </Wrapper> ); diff --git a/src/components/views/homepage/HomeIndex.tsx b/src/components/views/homepage/HomeIndex.tsx index 5c2e401fd8..49c5cc532a 100644 --- a/src/components/views/homepage/HomeIndex.tsx +++ b/src/components/views/homepage/HomeIndex.tsx @@ -19,7 +19,7 @@ import { FETCH_CAMPAIGNS_AND_FEATURED_PROJECTS } from '@/apollo/gql/gqlHomePage' import { LatestUpdatesBlock } from './latestUpdates/LatestUpdatesBlock'; import StorageLabel from '@/lib/localStorage'; import TorusBanner from './TorusBanner'; -// import AnnouncementBanner from './AnnouncementBanner'; +import AnnouncementBanner from './AnnouncementBanner'; const HomeIndex: FC<IHomeRoute> = props => { const { @@ -66,7 +66,7 @@ const HomeIndex: FC<IHomeRoute> = props => { return ( <Wrapper> - {/* <AnnouncementBanner /> */} + <AnnouncementBanner /> {showTorusBanner && <TorusBanner />} <IntroBlock /> <Separator /> diff --git a/src/components/views/nft/overview/CheckEligibility.tsx b/src/components/views/nft/overview/CheckEligibility.tsx index dd07905c50..e4fe64d194 100644 --- a/src/components/views/nft/overview/CheckEligibility.tsx +++ b/src/components/views/nft/overview/CheckEligibility.tsx @@ -11,14 +11,16 @@ import { import React, { ChangeEvent, useState } from 'react'; import styled from 'styled-components'; import { useAccount, useSwitchChain } from 'wagmi'; -import { Address } from 'viem'; +import { Abi, Address } from 'viem'; import { readContract } from '@wagmi/core'; -import { abi as PFP_ABI } from '@/artifacts/pfpGiver.json'; +import PFP_ARTIFACTS from '@/artifacts/pfpGiver.json'; import config from '@/configuration'; import { getAddressFromENS, isAddressENS } from '@/lib/wallet'; import EligibilityModal from './EligibilityModal'; import { wagmiConfig } from '@/wagmiConfigs'; +const PFP_ABI = PFP_ARTIFACTS.abi as Abi; + const CheckEligibility = () => { const [walletAddress, setWalletAddress] = useState(''); const [error, setError] = useState(''); diff --git a/src/components/views/project/ProjectGIVbackToast.tsx b/src/components/views/project/ProjectGIVbackToast.tsx index a547645023..2d17a4fab7 100644 --- a/src/components/views/project/ProjectGIVbackToast.tsx +++ b/src/components/views/project/ProjectGIVbackToast.tsx @@ -29,11 +29,11 @@ import { useModalCallback } from '@/hooks/useModalCallback'; import { isSSRMode } from '@/lib/helpers'; import BoostModal from '@/components/modals/Boost/BoostModal'; import { useAppSelector } from '@/features/hooks'; -import { formatDonation } from '@/helpers/number'; import { EProjectStatus } from '@/apollo/types/gqlEnums'; import { EVerificationStatus } from '@/apollo/types/types'; import Routes from '@/lib/constants/Routes'; import { VerificationModal } from '@/components/modals/VerificationModal'; +import { GIVBACKS_DONATION_QUALIFICATION_VALUE_USD } from '@/lib/constants/constants'; const ProjectGIVbackToast = () => { const [showBoost, setShowBoost] = useState(false); @@ -55,7 +55,7 @@ const ProjectGIVbackToast = () => { const color = isOwnerGivbackEligible ? semanticColors.golden[600] : neutralColors.gray[900]; - const { formatMessage, locale } = useIntl(); + const { formatMessage } = useIntl(); const { open: openConnectModal } = useWeb3Modal(); const { isEnabled, @@ -90,22 +90,19 @@ const ProjectGIVbackToast = () => { let title = ''; let description, Button; + const givbackFactorPercent = ((givbackFactor || 0) * 100).toFixed(); + if (isOwnerGivbackEligible) { if (givbackFactor !== 0) { - title = - formatMessage({ - id: `${useIntlTitle}verified_owner_1`, - }) + - formatDonation( - (givbackFactor || 0) * 100, - undefined, - locale, - true, - ) + - '%' + - formatMessage({ - id: `${useIntlTitle}verified_owner_2`, - }); + title = formatMessage( + { + id: `${useIntlTitle}verified_owner`, + }, + { + percent: givbackFactorPercent, + value: GIVBACKS_DONATION_QUALIFICATION_VALUE_USD, + }, + ); } description = formatMessage({ id: `${useIntlDescription}verified_owner`, @@ -268,9 +265,14 @@ const ProjectGIVbackToast = () => { id: `${useIntlTitle}verified_public_2`, }); } - description = formatMessage({ - id: `${useIntlDescription}verified_public`, - }); + description = formatMessage( + { + id: `${useIntlDescription}verified_public`, + }, + { + value: GIVBACKS_DONATION_QUALIFICATION_VALUE_USD, + }, + ); Button = ( <OutlineButton onClick={handleBoostClick} @@ -304,18 +306,6 @@ const ProjectGIVbackToast = () => { <div> <Title color={color}>{title} {description} - {isOwnerGivbackEligible && ( - - - {formatMessage({ - id: 'label.note', - }) + ' '} - - {formatMessage({ - id: 'project.givback_toast.description.verified_owner.note', - })} - - )} {link && ( { ); }; -const Note = styled(P)` - color: ${neutralColors.gray[800]}; - > span { - font-weight: 500; - } -`; - const LearnMore = styled(Caption)` display: flex; gap: 2px; - color: ${brandColors.pinky[500]}; + color: ${brandColors.pinky[500]} !important; `; const Description = styled(P)` @@ -375,7 +358,7 @@ const ButtonWrapper = styled.div` flex-direction: row-reverse; color: ${brandColors.giv[500]}; gap: 0; - width: 200px; + min-width: 180px; svg { margin-right: 8px; flex-shrink: 0; @@ -402,7 +385,7 @@ const Wrapper = styled(Flex)` border-radius: 16px; margin-top: 12px; flex-direction: column; - ${mediaQueries.tablet} { + ${mediaQueries.laptopL} { flex-direction: row; } `; diff --git a/src/components/views/transaction/DonationStatusSection.tsx b/src/components/views/transaction/DonationStatusSection.tsx index b03b0fc92e..a032b014ab 100644 --- a/src/components/views/transaction/DonationStatusSection.tsx +++ b/src/components/views/transaction/DonationStatusSection.tsx @@ -13,7 +13,7 @@ import { } from '@giveth/ui-design-system'; import { useIntl } from 'react-intl'; import { mediaQueries } from '@/lib/constants/constants'; -import { UsdAmountCard } from '@/components/views/donate/OnTime/SelectTokenModal/QRCodeDonation/QRDonationCard'; +import { UsdAmountCard } from '@/components/views/donate/OneTime/SelectTokenModal/QRCodeDonation/QRDonationCard'; import { TokenIcon } from '@/components/views/donate/TokenIcon/TokenIcon'; import config from '@/configuration'; import { smallDashedFormatDate } from '@/lib/helpers'; diff --git a/src/components/views/transaction/QRDetailsSection.tsx b/src/components/views/transaction/QRDetailsSection.tsx index 8f070b5970..7a3a1079c4 100644 --- a/src/components/views/transaction/QRDetailsSection.tsx +++ b/src/components/views/transaction/QRDetailsSection.tsx @@ -2,7 +2,7 @@ import React from 'react'; import styled from 'styled-components'; import { neutralColors, Flex } from '@giveth/ui-design-system'; import { mediaQueries } from '@/lib/constants/constants'; -import QRDonationCardContent from '@/components/views/donate/OnTime/SelectTokenModal/QRCodeDonation/QRDonationCardContent'; +import QRDonationCardContent from '@/components/views/donate/OneTime/SelectTokenModal/QRCodeDonation/QRDonationCardContent'; import { IDraftDonation, IProjectAcceptedToken } from '@/apollo/types/gqlTypes'; import { ChainType } from '@/types/config'; diff --git a/src/config/development.tsx b/src/config/development.tsx index a8f0699bef..11f737c951 100644 --- a/src/config/development.tsx +++ b/src/config/development.tsx @@ -78,7 +78,7 @@ const SOLANA_NETWORK: NonEVMChain = { }, }; -const STELLAR_NOTWORK: NonEVMChain = { +const STELLAR_NETWORK: NonEVMChain = { id: STELLAR_NETWORK_NUMBER, networkId: STELLAR_NETWORK_NUMBER, chainType: ChainType.STELLAR, @@ -128,7 +128,7 @@ const EVM_CHAINS = [ polygonZkEvmCardona, ] as readonly [Chain, ...Chain[]]; -const NON_EVM_CHAINS: NonEVMChain[] = [STELLAR_NOTWORK, SOLANA_NETWORK]; +const NON_EVM_CHAINS: NonEVMChain[] = [STELLAR_NETWORK, SOLANA_NETWORK]; const config: EnvConfig = { GIVETH_PROJECT_ID: 1, @@ -463,7 +463,7 @@ const config: EnvConfig = { }, }, STELLAR_CONFIG: { - ...STELLAR_NOTWORK, + ...STELLAR_NETWORK, chainType: ChainType.STELLAR, coingeckoChainName: 'stellar', chainLogo: (logoSize?: number) => , diff --git a/src/config/production.tsx b/src/config/production.tsx index 918c3b1053..88666e3a79 100644 --- a/src/config/production.tsx +++ b/src/config/production.tsx @@ -64,7 +64,7 @@ const SOLANA_NETWORK: NonEVMChain = { }, }; -const STELLAR_NOTWORK: NonEVMChain = { +const STELLAR_NETWORK: NonEVMChain = { id: STELLAR_NETWORK_NUMBER, networkId: STELLAR_NETWORK_NUMBER, chainType: ChainType.STELLAR, @@ -94,7 +94,7 @@ const EVM_CHAINS = [ polygonZkEvm, ] as readonly [Chain, ...Chain[]]; -const NON_EVM_CHAINS: NonEVMChain[] = [STELLAR_NOTWORK, SOLANA_NETWORK]; +const NON_EVM_CHAINS: NonEVMChain[] = [STELLAR_NETWORK, SOLANA_NETWORK]; const BASE_ROUTE = process.env.NEXT_PUBLIC_BASE_ROUTE || 'https://mainnet.serve.giveth.io'; @@ -615,7 +615,7 @@ const config: EnvConfig = { chainLogo: (logoSize?: number) => , }, STELLAR_CONFIG: { - ...STELLAR_NOTWORK, + ...STELLAR_NETWORK, coingeckoChainName: 'stellar', chainLogo: (logoSize?: number) => , }, diff --git a/src/configuration.ts b/src/configuration.ts index 756f91a3f1..5dba9b2b58 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -30,9 +30,20 @@ const EVM_NETWORKS_CONFIG = { }; const NON_EVM_NETWORKS_CONFIG: { [key: string]: NonEVMNetworkConfig } = {}; +const NON_EVM_NETWORKS_CONFIG_WITH_ID: { [key: number]: NonEVMNetworkConfig } = + {}; NON_EVM_NETWORKS_CONFIG[ChainType.SOLANA] = envConfig.SOLANA_CONFIG; NON_EVM_NETWORKS_CONFIG[ChainType.STELLAR] = envConfig.STELLAR_CONFIG; +NON_EVM_NETWORKS_CONFIG_WITH_ID[envConfig.SOLANA_CONFIG.networkId] = + envConfig.SOLANA_CONFIG; // 103 +if (!isProduction) { + // Cause Solana IDs are different in staging BE env + NON_EVM_NETWORKS_CONFIG_WITH_ID[101] = envConfig.SOLANA_CONFIG; + NON_EVM_NETWORKS_CONFIG_WITH_ID[102] = envConfig.SOLANA_CONFIG; +} +NON_EVM_NETWORKS_CONFIG_WITH_ID[envConfig.STELLAR_CONFIG.networkId] = + envConfig.STELLAR_CONFIG; const config: GlobalConfig = { TOKEN_NAME: 'DRGIV', @@ -47,6 +58,10 @@ const config: GlobalConfig = { EVM_NETWORKS_CONFIG, NON_EVM_NETWORKS_CONFIG, NETWORKS_CONFIG: { ...EVM_NETWORKS_CONFIG, ...NON_EVM_NETWORKS_CONFIG }, + NETWORKS_CONFIG_WITH_ID: { + ...EVM_NETWORKS_CONFIG, + ...NON_EVM_NETWORKS_CONFIG_WITH_ID, + }, CHAINS_WITH_SUBGRAPH: Object.entries(envConfig) .filter(([key, value]) => value?.subgraphAddress) .map(([key, value]) => value as NetworkConfig), diff --git a/src/context/donate.context.tsx b/src/context/donate.context.tsx index 21bbd7cb5c..cc5b6d7e94 100644 --- a/src/context/donate.context.tsx +++ b/src/context/donate.context.tsx @@ -10,8 +10,8 @@ import { useEffect, } from 'react'; import { useAccount } from 'wagmi'; -import { IProject } from '@/apollo/types/types'; -import { hasActiveRound } from '@/helpers/qf'; +import { IProject, IQFRound } from '@/apollo/types/types'; +import { getActiveRound, hasActiveRound } from '@/helpers/qf'; import { ISuperfluidStream, IToken } from '@/types/superFluid'; import { ChainType } from '@/types/config'; import { useUserStreams } from '@/hooks/useUserStreams'; @@ -33,6 +33,7 @@ interface ISuccessDonation { interface IDonateContext { hasActiveQFRound?: boolean; + activeStartedRound?: IQFRound; project: IProject; successDonation?: ISuccessDonation; tokenStreams: ITokenStreams; @@ -138,11 +139,15 @@ export const DonateProvider: FC = ({ children, project }) => { } = useQRCodeDonation(project); const hasActiveQFRound = hasActiveRound(project?.qfRounds); + const activeStartedRound = getActiveRound( + project?.qfRounds, + ).activeStartedRound; return ( { + if (!walletAddress || !tokens || tokens.length === 0) return []; + + // Filter out native tokens + const erc20Tokens: IProjectAcceptedToken[] = []; + const nativeTokens: IProjectAcceptedToken[] = []; + tokens.forEach(token => { + token.address !== AddressZero + ? erc20Tokens.push(token) + : nativeTokens.push(token); + }); + + const erc20Calls = erc20Tokens.map(token => ({ + address: token.address, + abi: erc20Abi, + functionName: 'balanceOf', + args: [walletAddress], + })); + + try { + // Fetch balances for ERC20 tokens via multicall + const erc20Results = await multicall(wagmiConfig, { + contracts: erc20Calls, + allowFailure: true, + }); + + // Fetch balances for native tokens (e.g., ETH) + const nativeTokenBalances = await Promise.all( + nativeTokens.map(async nativeToken => { + const balance = await getBalance(wagmiConfig, { + address: walletAddress as Address, + }); + return { + token: nativeToken, + balance: balance.value || 0n, + }; + }), + ); + + // Map ERC20 results to balances + const erc20Balances = erc20Results.map((result, index) => ({ + token: erc20Tokens[index], + balance: (result?.result as bigint) || 0n, + })); + + // Combine ERC20 and native token balances + return [...erc20Balances, ...nativeTokenBalances]; + } catch (error) { + console.error('Error fetching token balances:', error); + + // Return undefined balances in case of failure + return tokens.map(token => ({ token, balance: undefined })); + } +}; + export const fetchPriceWithCoingeckoId = async (coingeckoId: string) => { try { const res = await fetch( diff --git a/src/types/config.ts b/src/types/config.ts index b0b5bbdeaf..65e64c97e1 100644 --- a/src/types/config.ts +++ b/src/types/config.ts @@ -251,6 +251,9 @@ export interface GlobalConfig extends EnvConfig { NETWORKS_CONFIG: { [key: number | string]: NetworkConfig | NonEVMNetworkConfig; }; + NETWORKS_CONFIG_WITH_ID: { + [key: number]: NetworkConfig | NonEVMNetworkConfig; + }; CHAINS_WITH_SUBGRAPH: NetworkConfig[]; INFURA_API_KEY: string | undefined; BLOCKNATIVE_DAPP_ID: string | undefined; diff --git a/yarn.lock b/yarn.lock index b3b8f9e3c2..3630f770e5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2026,7 +2026,7 @@ "@metamask/sdk-communication-layer@0.28.2": version "0.28.2" - resolved "https://registry.yarnpkg.com/@metamask/sdk-communication-layer/-/sdk-communication-layer-0.28.2.tgz#25d84a6af4dd79324e0d4c9d1f307711fbd4aa91" + resolved "https://registry.npmjs.org/@metamask/sdk-communication-layer/-/sdk-communication-layer-0.28.2.tgz" integrity sha512-kGx6qgP482DecPILnIS38bgxIjNransR3/Jh5Lfg9BXJLaXpq/MEGrjHGnJHAqCyfRymnd5cgexHtXJvQtRWQA== dependencies: bufferutil "^4.0.8" @@ -2037,15 +2037,15 @@ "@metamask/sdk-install-modal-web@0.28.1": version "0.28.1" - resolved "https://registry.yarnpkg.com/@metamask/sdk-install-modal-web/-/sdk-install-modal-web-0.28.1.tgz#3e7085c34eaec7f9974e4a928e7f5bea33a278c9" + resolved "https://registry.npmjs.org/@metamask/sdk-install-modal-web/-/sdk-install-modal-web-0.28.1.tgz" integrity sha512-mHkIjWTpYQMPDMtLEEtTVXhae4pEjy7jDBfV7497L0U3VCPQrBl/giZBwA6AgKEX1emYcM2d1WRHWR9N4YhyJA== dependencies: qr-code-styling "^1.6.0-rc.1" -"@metamask/sdk@0.28.2": - version "0.28.2" - resolved "https://registry.yarnpkg.com/@metamask/sdk/-/sdk-0.28.2.tgz#99995a2cefd4bc6c4459869ee15c3b91ad02c488" - integrity sha512-pylk1uJAZYyO3HcNW/TNfII3+T+Yx6qrFYaC/HmuSIuRJeXsdZuExSbNQ236iQocIy3L7JjI+GQKbv3TbN+HQQ== +"@metamask/sdk@0.28.4": + version "0.28.4" + resolved "https://registry.npmjs.org/@metamask/sdk/-/sdk-0.28.4.tgz" + integrity sha512-RjWBKPNesjeua2SXIDF9IvYALOSsOQyqHv5DPPK0Voskytk7y+2n/33ocbC1BH5hTLI4hDPH+BuCpXJRWs3/Yg== dependencies: "@metamask/onboarding" "^1.0.1" "@metamask/providers" "16.1.0" @@ -4917,9 +4917,9 @@ "@types/react" "*" "@types/react@*", "@types/react@16 || 17 || 18", "@types/react@^18.0.15": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.3.tgz#9679020895318b0915d7a3ab004d92d33375c45f" - integrity sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw== + version "18.3.9" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.9.tgz#2cdf5f425ec8a133d67e9e3673909738b783db20" + integrity sha512-+BpAVyTpJkNWWSSnaLBk6ePpHLOGJKnEQNbINNovPWzvEUyAe3e+/d494QdEh71RekM/qV7lw6jzf1HGrJyAtQ== dependencies: "@types/prop-types" "*" csstype "^3.0.2" @@ -5186,13 +5186,13 @@ resolved "https://registry.npmjs.org/@vercel/speed-insights/-/speed-insights-1.0.10.tgz" integrity sha512-4uzdKB0RW6Ff2FkzshzjZ+RlJfLPxgm/00i0XXgxfMPhwnnsk92YgtqsxT9OcPLdJUyVU1DqFlSWWjIQMPkh0g== -"@wagmi/connectors@5.1.10": - version "5.1.10" - resolved "https://registry.yarnpkg.com/@wagmi/connectors/-/connectors-5.1.10.tgz#316dcdbb3924c546c177b0fc287e0f591225c63f" - integrity sha512-ybgKV09PIhgUgQ4atXTs2KOy4Hevd6f972SXfx6HTgsnFXlzxzN6o0aWjhavZOYjvx5tjuL3+8Mgqo0R7uP5Cg== +"@wagmi/connectors@5.1.11": + version "5.1.11" + resolved "https://registry.npmjs.org/@wagmi/connectors/-/connectors-5.1.11.tgz" + integrity sha512-k6IfxYHG0MqJWt2KY6UhrNt4mPSmCLq0tQG3h+uB5em1oioX9V902geoik+KoF6Sa0oqAq5UTJVA1IT5lAjOkQ== dependencies: "@coinbase/wallet-sdk" "4.0.4" - "@metamask/sdk" "0.28.2" + "@metamask/sdk" "0.28.4" "@safe-global/safe-apps-provider" "0.18.3" "@safe-global/safe-apps-sdk" "9.1.0" "@walletconnect/ethereum-provider" "2.16.1" @@ -5201,7 +5201,7 @@ "@wagmi/core@2.13.5": version "2.13.5" - resolved "https://registry.yarnpkg.com/@wagmi/core/-/core-2.13.5.tgz#20764d88d36c31c4557511309eef7d23fa60c98e" + resolved "https://registry.npmjs.org/@wagmi/core/-/core-2.13.5.tgz" integrity sha512-lvX/hApJTSA/H2kOklokjIYiUpnT8CpBH80GeOiKxU0CGK1wNHTu20GRTCy0GF1t7jkNwPSG3m0SmnXmgYMmHw== dependencies: eventemitter3 "5.0.1" @@ -5309,7 +5309,7 @@ "@walletconnect/ethereum-provider@2.16.1": version "2.16.1" - resolved "https://registry.yarnpkg.com/@walletconnect/ethereum-provider/-/ethereum-provider-2.16.1.tgz#4fb8a1df39104ad3fbd02579233e796f432f6d35" + resolved "https://registry.npmjs.org/@walletconnect/ethereum-provider/-/ethereum-provider-2.16.1.tgz" integrity sha512-oD7DNCssUX3plS5gGUZ9JQ63muQB/vxO68X6RzD2wd8gBsYtSPw4BqYFc7KTO6dUizD6gfPirw32yW2pTvy92w== dependencies: "@walletconnect/jsonrpc-http-connection" "1.0.8" @@ -5485,7 +5485,7 @@ "@walletconnect/sign-client@2.16.1": version "2.16.1" - resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.16.1.tgz#94a2f630ba741bd180f540c53576c5ceaace4857" + resolved "https://registry.npmjs.org/@walletconnect/sign-client/-/sign-client-2.16.1.tgz" integrity sha512-s2Tx2n2duxt+sHtuWXrN9yZVaHaYqcEcjwlTD+55/vs5NUPlISf+fFmZLwSeX1kUlrSBrAuxPUcqQuRTKcjLOA== dependencies: "@walletconnect/core" "2.16.1" @@ -5534,7 +5534,7 @@ "@walletconnect/types@2.16.1": version "2.16.1" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.16.1.tgz#6583d458d3f7b1919d482ba516ccb7878ec8c91f" + resolved "https://registry.npmjs.org/@walletconnect/types/-/types-2.16.1.tgz" integrity sha512-9P4RG4VoDEF+yBF/n2TF12gsvT/aTaeZTVDb/AOayafqiPnmrQZMKmNCJJjq1sfdsDcHXFcZWMGsuCeSJCmrXA== dependencies: "@walletconnect/events" "1.0.1" @@ -5546,12 +5546,12 @@ "@walletconnect/types@^1.8.0": version "1.8.0" - resolved "https://registry.npmjs.org/@walletconnect/types/-/types-1.8.0.tgz" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.8.0.tgz#3f5e85b2d6b149337f727ab8a71b8471d8d9a195" integrity sha512-Cn+3I0V0vT9ghMuzh1KzZvCkiAxTq+1TR2eSqw5E5AVWfmCtECFkVZBP6uUJZ8YjwLqXheI+rnjqPy7sVM4Fyg== "@walletconnect/universal-provider@2.16.1": version "2.16.1" - resolved "https://registry.yarnpkg.com/@walletconnect/universal-provider/-/universal-provider-2.16.1.tgz#6d52c41c7388e01f89007956a1117748ab9a11e4" + resolved "https://registry.npmjs.org/@walletconnect/universal-provider/-/universal-provider-2.16.1.tgz" integrity sha512-q/tyWUVNenizuClEiaekx9FZj/STU1F3wpDK4PUIh3xh+OmUI5fw2dY3MaNDjyb5AyrS0M8BuQDeuoSuOR/Q7w== dependencies: "@walletconnect/jsonrpc-http-connection" "1.0.8" @@ -5586,7 +5586,7 @@ "@walletconnect/utils@2.16.1": version "2.16.1" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.16.1.tgz#2099cc2bd16b0edc32022f64aa2c2c323b45d1d4" + resolved "https://registry.npmjs.org/@walletconnect/utils/-/utils-2.16.1.tgz" integrity sha512-aoQirVoDoiiEtYeYDtNtQxFzwO/oCrz9zqeEEXYJaAwXlGVTS34KFe7W3/Rxd/pldTYKFOZsku2EzpISfH8Wsw== dependencies: "@stablelib/chacha20poly1305" "1.0.1" @@ -5642,116 +5642,116 @@ bs58 "^5.0.0" valid-url "^1.0.9" -"@web3modal/base@5.1.7": - version "5.1.7" - resolved "https://registry.yarnpkg.com/@web3modal/base/-/base-5.1.7.tgz#f47511bc557b5da3d9bb9f0bcd94ac9272fab019" - integrity sha512-vPhfvm25b6GKh0kXYgR1PpUUbBaRdTqC5WuyQtCjlAovvVF7e4ouf4zeqVPM7+PTR/Tcbk3yuYzzcrlIgyyxmQ== +"@web3modal/base@5.1.8": + version "5.1.8" + resolved "https://registry.npmjs.org/@web3modal/base/-/base-5.1.8.tgz" + integrity sha512-zWBzGmhNegPDN69o6CkoclNybk4rmWQGxzYZxEU+wVMtNL593KyCgxaum0bGxVOjiShy0odgmsEE/z4P2HloZA== dependencies: "@walletconnect/utils" "2.16.1" - "@web3modal/common" "5.1.7" - "@web3modal/core" "5.1.7" - "@web3modal/polyfills" "5.1.7" - "@web3modal/scaffold-ui" "5.1.7" - "@web3modal/scaffold-utils" "5.1.7" - "@web3modal/siwe" "5.1.7" - "@web3modal/ui" "5.1.7" - "@web3modal/wallet" "5.1.7" + "@web3modal/common" "5.1.8" + "@web3modal/core" "5.1.8" + "@web3modal/polyfills" "5.1.8" + "@web3modal/scaffold-ui" "5.1.8" + "@web3modal/scaffold-utils" "5.1.8" + "@web3modal/siwe" "5.1.8" + "@web3modal/ui" "5.1.8" + "@web3modal/wallet" "5.1.8" optionalDependencies: borsh "0.7.0" bs58 "5.0.0" -"@web3modal/common@5.1.7": - version "5.1.7" - resolved "https://registry.yarnpkg.com/@web3modal/common/-/common-5.1.7.tgz#bc24764e7eea978f06c47f846d8240517d5643e3" - integrity sha512-LQGHCwO9ltsui3rHrxdkm3zFkE1Q8CyOjpaMw/0s8fNCZOO+pPn2XwkGXuh0vUbEx/P0dlM4JbVm1Fky/JndAA== +"@web3modal/common@5.1.8": + version "5.1.8" + resolved "https://registry.npmjs.org/@web3modal/common/-/common-5.1.8.tgz" + integrity sha512-W3tvTQ5FPauFjDSRIx3H6SurzzDHPeN3q7cMaxuOZb3Scf76vMkz9Af970Q44Jmlz1PGDKZzhEsmOzw6LJF+CA== dependencies: bignumber.js "9.1.2" dayjs "1.11.10" -"@web3modal/core@5.1.7": - version "5.1.7" - resolved "https://registry.yarnpkg.com/@web3modal/core/-/core-5.1.7.tgz#fd557a5f9201ab25cd0f4daa737137c5866325b5" - integrity sha512-PM0U/mgky1K62DU0jZO4v0Njj4yADs8xjtP8vY3cl+f//0CdNOMuzbnKEGfutni39JNKCRPOqiA43j8koaJGOQ== +"@web3modal/core@5.1.8": + version "5.1.8" + resolved "https://registry.npmjs.org/@web3modal/core/-/core-5.1.8.tgz" + integrity sha512-cdDCZP0JSuYofuMCZkFW2GkLqkFRxLSmFE/+8IJAWIwmDzEpvhkycQpbtkL7eNKah3Mm56ggQsF8jLDmcTJyYQ== dependencies: - "@web3modal/common" "5.1.7" - "@web3modal/wallet" "5.1.7" + "@web3modal/common" "5.1.8" + "@web3modal/wallet" "5.1.8" valtio "1.11.2" -"@web3modal/polyfills@5.1.7": - version "5.1.7" - resolved "https://registry.yarnpkg.com/@web3modal/polyfills/-/polyfills-5.1.7.tgz#1167f81ec94f7373ec61134dfd501a6e27370372" - integrity sha512-LZZRBjG5VldIxdyhYfWvt6TOULMxFK+ufYd6G73B3VZMRT4mDtZwF/qRhzdRnvzVE11Ou9JTPW5vsSV/8Ge6rA== +"@web3modal/polyfills@5.1.8": + version "5.1.8" + resolved "https://registry.npmjs.org/@web3modal/polyfills/-/polyfills-5.1.8.tgz" + integrity sha512-QtmwrFEomehyRDShL7hkcmDJuRQRStzgaHGRocNg52ScLw+uQYyHYNnqretRzUXNgfh+I6dy0olKO0Aj8Rw9Nw== dependencies: buffer "6.0.3" -"@web3modal/scaffold-ui@5.1.7": - version "5.1.7" - resolved "https://registry.yarnpkg.com/@web3modal/scaffold-ui/-/scaffold-ui-5.1.7.tgz#febd2461ba064b8f0dc9d7fb4e6e8770acb636ee" - integrity sha512-9PYLJQT5DFzj4/6jSI2oajHp7EksQDg7YVpDWoxghmYaJITrEtdYTKz4JF6b3TJTkNGG1qFJATy23Ayu0qQWzA== - dependencies: - "@web3modal/common" "5.1.7" - "@web3modal/core" "5.1.7" - "@web3modal/scaffold-utils" "5.1.7" - "@web3modal/siwe" "5.1.7" - "@web3modal/ui" "5.1.7" - "@web3modal/wallet" "5.1.7" +"@web3modal/scaffold-ui@5.1.8": + version "5.1.8" + resolved "https://registry.npmjs.org/@web3modal/scaffold-ui/-/scaffold-ui-5.1.8.tgz" + integrity sha512-/oOyCY+2wwgpHxlVPu3H0AqZocMQjKbPA8NLtt/YUVHQhcEusAx6NPmk0xb9PxBDrE1Qz00HFJ4QOco1yEFSTQ== + dependencies: + "@web3modal/common" "5.1.8" + "@web3modal/core" "5.1.8" + "@web3modal/scaffold-utils" "5.1.8" + "@web3modal/siwe" "5.1.8" + "@web3modal/ui" "5.1.8" + "@web3modal/wallet" "5.1.8" lit "3.1.0" -"@web3modal/scaffold-utils@5.1.7": - version "5.1.7" - resolved "https://registry.yarnpkg.com/@web3modal/scaffold-utils/-/scaffold-utils-5.1.7.tgz#cb9ce5735eec2a6940bde768aeb79ef33b8515f3" - integrity sha512-bS4k2x2Ddfae+YXzn0e5iTm60Pb+4d8t64bRDpBQqQhbbA1ppSudZpfrUHQ8NeBti7sg8cpOd+ofDGuIFQzYlA== +"@web3modal/scaffold-utils@5.1.8": + version "5.1.8" + resolved "https://registry.npmjs.org/@web3modal/scaffold-utils/-/scaffold-utils-5.1.8.tgz" + integrity sha512-Eh0Z9uhOvqYID4T5k/T+rh8nr9U6BrlZbJGkD5DQeidMCwnq5IDnt8v4xCjyZoPRKu3KZS3goBItEwXLwOTiIg== dependencies: - "@web3modal/common" "5.1.7" - "@web3modal/core" "5.1.7" - "@web3modal/polyfills" "5.1.7" - "@web3modal/wallet" "5.1.7" + "@web3modal/common" "5.1.8" + "@web3modal/core" "5.1.8" + "@web3modal/polyfills" "5.1.8" + "@web3modal/wallet" "5.1.8" valtio "1.11.2" -"@web3modal/siwe@5.1.7": - version "5.1.7" - resolved "https://registry.yarnpkg.com/@web3modal/siwe/-/siwe-5.1.7.tgz#ef3b609e4227d21ed793130d74f36545316c520c" - integrity sha512-j1pIHh7XkVdcjav8DzQV7ZKdcyr5qUjbXFY3/KGUWWcwNE8m5Az1GdSqGkt4luWLLjTNpZ2mOcL/dmFD6tg8Gg== +"@web3modal/siwe@5.1.8": + version "5.1.8" + resolved "https://registry.npmjs.org/@web3modal/siwe/-/siwe-5.1.8.tgz" + integrity sha512-twlQ28A32ZiJNXppV3L/ByveigPtngEqyju9tT2EZlN+6BPXRJg7ZTv97viOaJTKfnApfFYOBB0wE8pBuC49Lg== dependencies: "@walletconnect/utils" "2.16.1" - "@web3modal/common" "5.1.7" - "@web3modal/core" "5.1.7" - "@web3modal/scaffold-utils" "5.1.7" - "@web3modal/ui" "5.1.7" - "@web3modal/wallet" "5.1.7" + "@web3modal/common" "5.1.8" + "@web3modal/core" "5.1.8" + "@web3modal/scaffold-utils" "5.1.8" + "@web3modal/ui" "5.1.8" + "@web3modal/wallet" "5.1.8" lit "3.1.0" valtio "1.11.2" -"@web3modal/ui@5.1.7": - version "5.1.7" - resolved "https://registry.yarnpkg.com/@web3modal/ui/-/ui-5.1.7.tgz#83b5cb5c63e2ff82d09713aaf6181f74ef35e5cb" - integrity sha512-f1qwO+28cR7o6OELdsGaE4Juvk22MC7Ro2gOnN+8VCQ0V8v33Z9jPtKdgFI/+2qg2fYKuR9pQX029vPPIqvg4A== +"@web3modal/ui@5.1.8": + version "5.1.8" + resolved "https://registry.npmjs.org/@web3modal/ui/-/ui-5.1.8.tgz" + integrity sha512-M42datuMhDwj+AATw3TqgLLlame2kac4X+3cAMqQ3JRY5a2M/Oz9vXQ0UuOVBxuFpVqioMnQvBiXwjyvdkkO4Q== dependencies: lit "3.1.0" qrcode "1.5.3" "@web3modal/wagmi@^5.1.7": - version "5.1.7" - resolved "https://registry.yarnpkg.com/@web3modal/wagmi/-/wagmi-5.1.7.tgz#50455377541de0d22698f7afa2f6dd5a18523aeb" - integrity sha512-6S0ilGAoPwupyOpgG7B1dSuWXOhiHI5AfKk9XTARcwcBHXV053CwA3cSjo6D1Q/KFGCKoFOTKpkm56BFXJA6NA== + version "5.1.8" + resolved "https://registry.npmjs.org/@web3modal/wagmi/-/wagmi-5.1.8.tgz" + integrity sha512-xB8Mp0EDP9ErCa0qfuTGM7sfyLzfza5iWGWKSZOPWM1xwonLtk7+aqTtJOcsaNmbxZvBhV/OVg+UWNe2u7TFdg== dependencies: "@walletconnect/ethereum-provider" "2.16.1" "@walletconnect/utils" "2.16.1" - "@web3modal/base" "5.1.7" - "@web3modal/common" "5.1.7" - "@web3modal/polyfills" "5.1.7" - "@web3modal/scaffold-utils" "5.1.7" - "@web3modal/siwe" "5.1.7" - "@web3modal/wallet" "5.1.7" - -"@web3modal/wallet@5.1.7": - version "5.1.7" - resolved "https://registry.yarnpkg.com/@web3modal/wallet/-/wallet-5.1.7.tgz#ab8a4f95f2bd6c78e9632107b13d14d10df8deaf" - integrity sha512-RQW1GOlp+DLmtq/Qx6vzofcleYHMkU6feocfbNzutG3AYxxmOsD9DbPSKB84ZYwROzsP+VVpOr9L+qEkMnGkzg== + "@web3modal/base" "5.1.8" + "@web3modal/common" "5.1.8" + "@web3modal/polyfills" "5.1.8" + "@web3modal/scaffold-utils" "5.1.8" + "@web3modal/siwe" "5.1.8" + "@web3modal/wallet" "5.1.8" + +"@web3modal/wallet@5.1.8": + version "5.1.8" + resolved "https://registry.npmjs.org/@web3modal/wallet/-/wallet-5.1.8.tgz" + integrity sha512-FpIqOE6YrKc4w70qmYeePaVjELKM8d4fEefnQD7ROPnoOsqbbd9lWF0XYhOr+iD6eG+yaVKc4XFN0NDbw+lDdA== dependencies: "@walletconnect/logger" "2.1.2" - "@web3modal/common" "5.1.7" - "@web3modal/polyfills" "5.1.7" + "@web3modal/common" "5.1.8" + "@web3modal/polyfills" "5.1.8" zod "3.22.4" "@wry/caches@^1.0.0": @@ -8418,22 +8418,9 @@ elliptic@6.5.4: minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" -elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4, elliptic@^6.5.5: - version "6.5.5" - resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.5.tgz" - integrity sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw== - dependencies: - bn.js "^4.11.9" - brorand "^1.1.0" - hash.js "^1.0.0" - hmac-drbg "^1.0.1" - inherits "^2.0.4" - minimalistic-assert "^1.0.1" - minimalistic-crypto-utils "^1.0.1" - -elliptic@^6.5.7: +elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4, elliptic@^6.5.5, elliptic@^6.5.7: version "6.5.7" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.7.tgz#8ec4da2cb2939926a1b9a73619d768207e647c8b" + resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz" integrity sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q== dependencies: bn.js "^4.11.9" @@ -12006,13 +11993,13 @@ lit-element@^3.3.0: lit-html "^2.8.0" lit-element@^4.0.0: - version "4.0.5" - resolved "https://registry.npmjs.org/lit-element/-/lit-element-4.0.5.tgz" - integrity sha512-iTWskWZEtn9SyEf4aBG6rKT8GABZMrTWop1+jopsEOgEcugcXJGKuX5bEbkq9qfzY+XB4MAgCaSPwnNpdsNQ3Q== + version "4.1.0" + resolved "https://registry.npmjs.org/lit-element/-/lit-element-4.1.0.tgz" + integrity sha512-gSejRUQJuMQjV2Z59KAS/D4iElUhwKpIyJvZ9w+DIagIQjfJnhR20h2Q5ddpzXGS+fF0tMZ/xEYGMnKmaI/iww== dependencies: "@lit-labs/ssr-dom-shim" "^1.2.0" "@lit/reactive-element" "^2.0.4" - lit-html "^3.1.2" + lit-html "^3.2.0" lit-html@^2.8.0: version "2.8.0" @@ -12021,10 +12008,10 @@ lit-html@^2.8.0: dependencies: "@types/trusted-types" "^2.0.2" -lit-html@^3.1.0, lit-html@^3.1.2: - version "3.1.3" - resolved "https://registry.npmjs.org/lit-html/-/lit-html-3.1.3.tgz" - integrity sha512-FwIbqDD8O/8lM4vUZ4KvQZjPPNx7V1VhT7vmRB8RBAO0AU6wuTVdoXiu2CivVjEGdugvcbPNBLtPE1y0ifplHA== +lit-html@^3.1.0, lit-html@^3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/lit-html/-/lit-html-3.2.0.tgz" + integrity sha512-pwT/HwoxqI9FggTrYVarkBKFN9MlTUpLrDHubTmW4SrkL3kkqW5gxwbxMMUnbbRHBC0WTZnYHcjDSCM559VyfA== dependencies: "@types/trusted-types" "^2.0.2" @@ -15559,7 +15546,7 @@ strip-json-comments@^2.0.0: styled-components@^6.1.12, styled-components@^6.1.8: version "6.1.13" - resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-6.1.13.tgz#2d777750b773b31469bd79df754a32479e9f475e" + resolved "https://registry.npmjs.org/styled-components/-/styled-components-6.1.13.tgz" integrity sha512-M0+N2xSnAtwcVAQeFEsGWFFxXDftHUD7XrKla06QbpUMmbmtFBMMTcKWvFXtWxuD5qQkB8iU5gk6QASlx2ZRMw== dependencies: "@emotion/is-prop-valid" "1.2.2" @@ -16584,11 +16571,11 @@ w3c-xmlserializer@^4.0.0: xml-name-validator "^4.0.0" wagmi@^2.12.10: - version "2.12.10" - resolved "https://registry.yarnpkg.com/wagmi/-/wagmi-2.12.10.tgz#e212db1f86bf5522063494244e19676877dc6ccd" - integrity sha512-aSG0fW+Kft62syxAWkmSaMku5CZRW6Q2lsu64bLvLLVyZgZMt8+qQRdYk8WcFFdBzivkuDMRMREMxw7dwdImkw== + version "2.12.12" + resolved "https://registry.npmjs.org/wagmi/-/wagmi-2.12.12.tgz" + integrity sha512-BgB8GprWJzWuq3V6vCr12kP9a+ta9AWEkoM/fjQWE90yD9YWEgYmpK/uqXNnZLymsuSfxyIFn7JhYIs+mwo/yA== dependencies: - "@wagmi/connectors" "5.1.10" + "@wagmi/connectors" "5.1.11" "@wagmi/core" "2.13.5" use-sync-external-store "1.2.0"