From 2e3663e217a54e883b16c406c7c8e6cdc95cbbb3 Mon Sep 17 00:00:00 2001 From: Tomas Date: Fri, 1 Nov 2024 04:37:41 -0300 Subject: [PATCH 1/5] [feat] added share page for NFTs --- src/app/nfts/share/[id]/layout.tsx | 13 ++ src/app/nfts/share/[id]/page.tsx | 11 ++ src/app/nfts/share/page.tsx | 7 + src/locales/langs/br.json | 4 + src/locales/langs/en.json | 4 + src/locales/langs/es.json | 4 + src/sections/nfts/nft-item-share.tsx | 207 ++++++++++++++++++++++ src/sections/nfts/view/nft-share-view.tsx | 50 ++++++ 8 files changed, 300 insertions(+) create mode 100644 src/app/nfts/share/[id]/layout.tsx create mode 100644 src/app/nfts/share/[id]/page.tsx create mode 100644 src/app/nfts/share/page.tsx create mode 100644 src/sections/nfts/nft-item-share.tsx create mode 100644 src/sections/nfts/view/nft-share-view.tsx diff --git a/src/app/nfts/share/[id]/layout.tsx b/src/app/nfts/share/[id]/layout.tsx new file mode 100644 index 0000000..d231c94 --- /dev/null +++ b/src/app/nfts/share/[id]/layout.tsx @@ -0,0 +1,13 @@ +'use client' + +import MainLayout from 'src/layouts/main' + +// ---------------------------------------------------------------------- + +type Props = { + children: React.ReactNode +} + +export default function Layout({ children }: Props) { + return {children} +} diff --git a/src/app/nfts/share/[id]/page.tsx b/src/app/nfts/share/[id]/page.tsx new file mode 100644 index 0000000..94253fa --- /dev/null +++ b/src/app/nfts/share/[id]/page.tsx @@ -0,0 +1,11 @@ +import NftShareView from 'src/sections/nfts/view/nft-share-view' + +// ---------------------------------------------------------------------- + +export const metadata = { + title: 'NFT Share' +} + +export default function NftMintPage({ params }: { params: { id: string } }) { + return +} diff --git a/src/app/nfts/share/page.tsx b/src/app/nfts/share/page.tsx new file mode 100644 index 0000000..e0c8ab5 --- /dev/null +++ b/src/app/nfts/share/page.tsx @@ -0,0 +1,7 @@ +import { redirect } from 'next/navigation' + +// ---------------------------------------------------------------------- + +export default function Share() { + return redirect('/') +} diff --git a/src/locales/langs/br.json b/src/locales/langs/br.json index 527eb7a..61a34b6 100644 --- a/src/locales/langs/br.json +++ b/src/locales/langs/br.json @@ -335,6 +335,10 @@ "cta-msg": "Reivindique seu certificado na blockchain gratuitamente!", "opensea-alt": "logo open sea", "wapp-msg": "Gostaria de mintar o NFT" + }, + "share": { + "cta": "Compartilhar certificado", + "close": "Fechar" } }, "account": { diff --git a/src/locales/langs/en.json b/src/locales/langs/en.json index 92815ce..54df840 100644 --- a/src/locales/langs/en.json +++ b/src/locales/langs/en.json @@ -335,6 +335,10 @@ "cta-msg": "Claim your certificate on the blockchain for free!", "opensea-alt": "open sea logo", "wapp-msg": "I would like to mint the NFT" + }, + "share": { + "cta": "Share", + "close": "Close" } }, "account": { diff --git a/src/locales/langs/es.json b/src/locales/langs/es.json index 3f6377e..bd6bfb2 100644 --- a/src/locales/langs/es.json +++ b/src/locales/langs/es.json @@ -336,6 +336,10 @@ "cta-msg": "¡Reclamá tu certificado en blockchain gratis!", "opensea-alt": "logo open sea", "wapp-msg": "Me gustaría mintear el NFT" + }, + "share": { + "cta": "Compartir", + "close": "Cerrar" } }, "account": { diff --git a/src/sections/nfts/nft-item-share.tsx b/src/sections/nfts/nft-item-share.tsx new file mode 100644 index 0000000..856b6af --- /dev/null +++ b/src/sections/nfts/nft-item-share.tsx @@ -0,0 +1,207 @@ +import Image from 'next/image' +import { useState } from 'react' +import { m } from 'framer-motion' +import { Icon } from '@iconify/react' + +import { Box, Stack } from '@mui/system' +import { Card, Button, Dialog, Typography, IconButton, DialogTitle, DialogContent, DialogActions } from '@mui/material' + +import { useResponsive } from 'src/hooks/use-responsive' + +import { useTranslate } from 'src/locales' +import { NFT_MARKETPLACE_URL, NFT_IMAGE_REPOSITORY } from 'src/config-global' + +import { varFade } from 'src/components/animate' + +import { INFT, ImageURLRepository } from 'src/types/wallet' + +// ---------------------------------------------------------------------- + +type NftItemClaimProps = { + nftId: string + nftData: INFT +} + +export default function NftItemShare({ nftId, nftData }: NftItemClaimProps) { + const mdUp = useResponsive('up', 'md') + const { t } = useTranslate() + const [openShare, setOpenShare] = useState(false) + + const handleOpenOpenSea = () => { + const url = `${NFT_MARKETPLACE_URL}/${nftId}` + window.open(url, '_blank') + } + + const handleShare = (platform: string) => { + const nftUrl = `${NFT_MARKETPLACE_URL}/${nftId}` + const text = nftData.metadata.description + + const shareUrls = { + twitter: `https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}&url=${encodeURIComponent(nftUrl)}`, + facebook: `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(nftUrl)}`, + whatsapp: `https://wa.me/?text=${encodeURIComponent(`${text} ${nftUrl}`)}`, + linkedin: `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(nftUrl)}`, + } as const + + window.open(shareUrls[platform as keyof typeof shareUrls], '_blank') + } + + const handleCopyLink = async () => { + try { + await navigator.clipboard.writeText(`${NFT_MARKETPLACE_URL}/${nftId}`) + // Aquí podrías mostrar un Snackbar de éxito + } catch (err) { + console.error('Error al copiar:', err) + } + } + + let imageUrl = nftData.metadata.image_url[NFT_IMAGE_REPOSITORY as ImageURLRepository] + ? nftData.metadata.image_url[NFT_IMAGE_REPOSITORY as ImageURLRepository] + : nftData.metadata.image_url.gcp + imageUrl = imageUrl || '/assets/images/nfts/default_nft.png' + + const handleTriggerShare = async () => { + if (!openShare && !navigator.share) { + try { + await navigator.share({ + title: nftData.metadata.description, + url: `${NFT_MARKETPLACE_URL}/${nftId}` + }) + } catch (err) { + console.error('Error al compartir:', err) + } + } else { + setOpenShare(!openShare) + } + } + + const socialButtons = [ + { icon: 'ri:twitter-x-fill', name: 'Twitter', action: () => handleShare('twitter') }, + { icon: 'ri:whatsapp-fill', name: 'WhatsApp', action: () => handleShare('whatsapp') }, + { icon: 'ri:linkedin-box-fill', name: 'LinkedIn', action: () => handleShare('linkedin') }, + { icon: 'ri:facebook-circle-fill', name: 'Facebook', action: () => handleShare('facebook') }, + { icon: 'ri:links-fill', name: 'Copiar Link', action: handleCopyLink }, + ] + + return ( + + + + {nftData.metadata.description} + + + + + + {nftData.metadata.description} + + + {/* Botones flotantes */} + + + setOpenShare(true)} + sx={{ + backgroundColor: 'white', + '&:hover': { backgroundColor: 'rgba(255,255,255,0.9)' } + }} + > + + + + + + {t('nfts.claim.opensea-alt')} + + + + + + + + + + {/* Diálogo de compartir */} + + {t('nfts.share.cta')} + + + {socialButtons.map((button) => ( + + ))} + + + + + + + + ) +} \ No newline at end of file diff --git a/src/sections/nfts/view/nft-share-view.tsx b/src/sections/nfts/view/nft-share-view.tsx new file mode 100644 index 0000000..3f327f8 --- /dev/null +++ b/src/sections/nfts/view/nft-share-view.tsx @@ -0,0 +1,50 @@ +'use client' + +import Container from '@mui/material/Container' + +import { useTranslate } from 'src/locales' +import { useGetNftById } from 'src/app/api/_hooks' + +import EmptyContent from 'src/components/empty-content' +import { useSettingsContext } from 'src/components/settings' +import { LoadingScreen } from 'src/components/loading-screen' + +import { INFT } from 'src/types/wallet' + +import NftItemShare from '../nft-item-share' + +// ---------------------------------------------------------------------- + +type NftItemProps = { + nftId: string +} +export default function NftShareView({ nftId }: NftItemProps) { + const { t } = useTranslate() + const settings = useSettingsContext() + + const { + data: nftData, + isLoading + }: { + data: INFT + isLoading: boolean + } = useGetNftById(nftId) + + const notFound = !nftData + + const renderContent = ( + <> + {notFound ? ( + + ) : ( + + )} + + ) + + return ( + + {isLoading ? : renderContent} + + ) +} From 423b7cc79e6c0a3e5bf985b5fe6cc87e4bc4e713 Mon Sep 17 00:00:00 2001 From: dappsar Date: Fri, 1 Nov 2024 07:43:02 -0300 Subject: [PATCH 2/5] [feat] :sparkles: added msg after copy clipboard (#139) --- src/sections/nfts/nft-item-share.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sections/nfts/nft-item-share.tsx b/src/sections/nfts/nft-item-share.tsx index 856b6af..93810e3 100644 --- a/src/sections/nfts/nft-item-share.tsx +++ b/src/sections/nfts/nft-item-share.tsx @@ -26,6 +26,7 @@ export default function NftItemShare({ nftId, nftData }: NftItemClaimProps) { const mdUp = useResponsive('up', 'md') const { t } = useTranslate() const [openShare, setOpenShare] = useState(false) + const { enqueueSnackbar } = useSnackbar() const handleOpenOpenSea = () => { const url = `${NFT_MARKETPLACE_URL}/${nftId}` @@ -49,7 +50,7 @@ export default function NftItemShare({ nftId, nftData }: NftItemClaimProps) { const handleCopyLink = async () => { try { await navigator.clipboard.writeText(`${NFT_MARKETPLACE_URL}/${nftId}`) - // Aquí podrías mostrar un Snackbar de éxito + enqueueSnackbar(t('nfts.share.clipboard'), { variant: 'info' }) } catch (err) { console.error('Error al copiar:', err) } From 50b136f80b9d50bb1bd3ef4c4d9643f48963a3a6 Mon Sep 17 00:00:00 2001 From: dappsar Date: Fri, 1 Nov 2024 07:43:43 -0300 Subject: [PATCH 3/5] [feat] :sparkles: improve close button (#139) --- src/sections/nfts/nft-item-share.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sections/nfts/nft-item-share.tsx b/src/sections/nfts/nft-item-share.tsx index 93810e3..c12af63 100644 --- a/src/sections/nfts/nft-item-share.tsx +++ b/src/sections/nfts/nft-item-share.tsx @@ -200,7 +200,9 @@ export default function NftItemShare({ nftId, nftData }: NftItemClaimProps) { - + From 45b020cd52b8407a29be515206ea253ed045e6c5 Mon Sep 17 00:00:00 2001 From: dappsar Date: Fri, 1 Nov 2024 07:44:32 -0300 Subject: [PATCH 4/5] [feat] :globe_with_meridians: update i18n for nfts-share (#139) --- src/locales/langs/br.json | 12 ++++++------ src/locales/langs/en.json | 14 +++++++------- src/locales/langs/es.json | 9 ++++----- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/locales/langs/br.json b/src/locales/langs/br.json index 61a34b6..2181f0d 100644 --- a/src/locales/langs/br.json +++ b/src/locales/langs/br.json @@ -11,7 +11,7 @@ "required": "obrigatório", "must-be-numeric": "Deve ser numérico", "must-be-max": "Deve ter no máximo {MAX_DIGITS} dígitos", - "must-be-valid-email": "O email deve ser um endereço de email válido", + "must-be-valid-email": "O email deve ser um endereço de email válido", "must-be-min": "Deve ter no mínimo {MIN_CHARS} caracteres", "nodata": "Sem Dados", "save": "Salvar Alterações", @@ -250,7 +250,7 @@ "answer": "Digite seu número de telefone registrado. Um código de 6 dígitos será enviado para o seu telefone por segurança; depois de inseri-lo, você poderá acessar o site." } } - }, + }, "get-started": { "title": "Comece com", "description": "Todo o poder do Web3 sem complicações.", @@ -310,8 +310,8 @@ "transfer-all": { "info": "Indica um endereço de carteira para onde serão enviados todos os fundos que você possui no Chatterpay.", "msgs": { - "ok": "Os fundos foram transferidos. Você os verá na carteira indicada em breve.", - "error": "Houve um erro ao tentar transferir os fundos." + "ok": "Os fundos foram transferidos. Você os verá na carteira indicada em breve.", + "error": "Houve um erro ao tentar transferir os fundos." }, "actions": { "transfer": "Transferir Tudo" @@ -338,7 +338,7 @@ }, "share": { "cta": "Compartilhar certificado", - "close": "Fechar" + "clipboard": "Link copiado!" } }, "account": { @@ -356,4 +356,4 @@ "code-bot": "Insira este código {2FA_CODE} para validar a alteração do seu e-mail no Chatterpay. É muito importante que você não compartilhe esta informação com ninguém. Se você não solicitou o código, desconsidere esta mensagem e entre em contato conosco para que possamos ajudá-lo!" } } -} +} \ No newline at end of file diff --git a/src/locales/langs/en.json b/src/locales/langs/en.json index 54df840..0cf153e 100644 --- a/src/locales/langs/en.json +++ b/src/locales/langs/en.json @@ -38,8 +38,8 @@ }, "home": { "header": { - "sign-up": "Create your account", - "sign-in": "Sign in" + "sign-up": "Create your account", + "sign-in": "Sign in" }, "help": { "need-help": "Need help?" @@ -293,12 +293,12 @@ "send": "Send", "transfer-all": "Transfer All", "wapp-msg": "Hi!" - }, + }, "transactions": { "title": "Recent Transactions", "table-transaction": "Transaction", "table-amount": "Amount", - "table-date": "Date", + "table-date": "Date", "table-status": "Status", "table-view-all": "View All", "table-download": "Download", @@ -310,8 +310,8 @@ "transfer-all": { "info": "Indicates a wallet address where all funds in Chatterpay will be sent.", "msgs": { - "ok": "The funds were transferred. You will see them in the indicated wallet shortly.", - "error": "There was an error attempting to transfer the funds." + "ok": "The funds were transferred. You will see them in the indicated wallet shortly.", + "error": "There was an error attempting to transfer the funds." }, "actions": { "transfer": "Transfer All" @@ -338,7 +338,7 @@ }, "share": { "cta": "Share", - "close": "Close" + "clipboard": "Link copied!" } }, "account": { diff --git a/src/locales/langs/es.json b/src/locales/langs/es.json index bd6bfb2..c714799 100644 --- a/src/locales/langs/es.json +++ b/src/locales/langs/es.json @@ -102,7 +102,7 @@ "home": { "header": { "sign-up": "Creá tu cuenta", - "sign-in": "Ingresá" + "sign-in": "Ingresá" }, "help": { "need-help": "¿Necesita ayuda?" @@ -250,7 +250,7 @@ "answer": "Ingresa tu número de teléfono registrado. Se enviará un código de 6 dígitos a tu teléfono por seguridad; una vez que lo ingreses, podrás acceder al sitio." } } - }, + }, "get-started": { "title": "Comienza con", "description": "Todo el poder de Web3 sin complicaciones.", @@ -329,7 +329,6 @@ "meta-geo": "Geolocalización", "original": "Original", "copy-of": "Copia #{X} de #{Z}" - }, "claim": { "cta": "Reclamar", @@ -339,7 +338,7 @@ }, "share": { "cta": "Compartir", - "close": "Cerrar" + "clipboard": "Link copiado!" } }, "account": { @@ -357,4 +356,4 @@ "code-bot": "Ingresá este código *{2FA_CODE}* para validar tu cambio de correo electrónico en Chatterpay. Es muy importante que no compartas esta información con nadie. Si no solicitaste el código, desestimá este mensaje y contactate con nosotros para que podamos ayudarte!" } } -} +} \ No newline at end of file From 0792e87f44739c8d1c4d162a4239628d47cff9ea Mon Sep 17 00:00:00 2001 From: dappsar Date: Fri, 1 Nov 2024 07:44:57 -0300 Subject: [PATCH 5/5] [feat] :lipstick: prettier & linter (#139) --- src/sections/nfts/nft-item-share.tsx | 58 ++++++++++++++++------------ 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/src/sections/nfts/nft-item-share.tsx b/src/sections/nfts/nft-item-share.tsx index c12af63..3c4ac32 100644 --- a/src/sections/nfts/nft-item-share.tsx +++ b/src/sections/nfts/nft-item-share.tsx @@ -2,9 +2,19 @@ import Image from 'next/image' import { useState } from 'react' import { m } from 'framer-motion' import { Icon } from '@iconify/react' +import { useSnackbar } from 'notistack' import { Box, Stack } from '@mui/system' -import { Card, Button, Dialog, Typography, IconButton, DialogTitle, DialogContent, DialogActions } from '@mui/material' +import { + Card, + Button, + Dialog, + IconButton, + Typography, + DialogTitle, + DialogActions, + DialogContent +} from '@mui/material' import { useResponsive } from 'src/hooks/use-responsive' @@ -36,12 +46,12 @@ export default function NftItemShare({ nftId, nftData }: NftItemClaimProps) { const handleShare = (platform: string) => { const nftUrl = `${NFT_MARKETPLACE_URL}/${nftId}` const text = nftData.metadata.description - + const shareUrls = { twitter: `https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}&url=${encodeURIComponent(nftUrl)}`, facebook: `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(nftUrl)}`, whatsapp: `https://wa.me/?text=${encodeURIComponent(`${text} ${nftUrl}`)}`, - linkedin: `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(nftUrl)}`, + linkedin: `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(nftUrl)}` } as const window.open(shareUrls[platform as keyof typeof shareUrls], '_blank') @@ -81,7 +91,7 @@ export default function NftItemShare({ nftId, nftData }: NftItemClaimProps) { { icon: 'ri:whatsapp-fill', name: 'WhatsApp', action: () => handleShare('whatsapp') }, { icon: 'ri:linkedin-box-fill', name: 'LinkedIn', action: () => handleShare('linkedin') }, { icon: 'ri:facebook-circle-fill', name: 'Facebook', action: () => handleShare('facebook') }, - { icon: 'ri:links-fill', name: 'Copiar Link', action: handleCopyLink }, + { icon: 'ri:links-fill', name: 'Copiar Link', action: handleCopyLink } ] return ( @@ -98,7 +108,7 @@ export default function NftItemShare({ nftId, nftData }: NftItemClaimProps) { mb: mdUp ? 0 : 5 }} > - {nftData.metadata.description} + {nftData.metadata.description} - + {/* Botones flotantes */} setOpenShare(true)} - sx={{ + sx={{ backgroundColor: 'white', '&:hover': { backgroundColor: 'rgba(255,255,255,0.9)' } }} > - + - + {/* Diálogo de compartir */} - + {t('nfts.share.cta')} - + {socialButtons.map((button) => ( ) -} \ No newline at end of file +}