Skip to content

Commit

Permalink
Merge pull request #138 from P4-Games/feat/share-nfts
Browse files Browse the repository at this point in the history
merge feat/share-nfts into develop
  • Loading branch information
dappsar authored Nov 1, 2024
2 parents 1d0d512 + 0792e87 commit c4102c3
Show file tree
Hide file tree
Showing 8 changed files with 325 additions and 15 deletions.
13 changes: 13 additions & 0 deletions src/app/nfts/share/[id]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
'use client'

import MainLayout from 'src/layouts/main'

// ----------------------------------------------------------------------

type Props = {
children: React.ReactNode
}

export default function Layout({ children }: Props) {
return <MainLayout>{children}</MainLayout>
}
11 changes: 11 additions & 0 deletions src/app/nfts/share/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -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 <NftShareView nftId={params.id} />
}
7 changes: 7 additions & 0 deletions src/app/nfts/share/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { redirect } from 'next/navigation'

// ----------------------------------------------------------------------

export default function Share() {
return redirect('/')
}
14 changes: 9 additions & 5 deletions src/locales/langs/br.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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.",
Expand Down Expand Up @@ -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"
Expand All @@ -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",
"clipboard": "Link copiado!"
}
},
"account": {
Expand All @@ -352,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!"
}
}
}
}
16 changes: 10 additions & 6 deletions src/locales/langs/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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?"
Expand Down Expand Up @@ -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",
Expand All @@ -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"
Expand All @@ -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",
"clipboard": "Link copied!"
}
},
"account": {
Expand Down
11 changes: 7 additions & 4 deletions src/locales/langs/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
"home": {
"header": {
"sign-up": "Creá tu cuenta",
"sign-in": "Ingresá"
"sign-in": "Ingresá"
},
"help": {
"need-help": "¿Necesita ayuda?"
Expand Down Expand Up @@ -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.",
Expand Down Expand Up @@ -329,13 +329,16 @@
"meta-geo": "Geolocalización",
"original": "Original",
"copy-of": "Copia #{X} de #{Z}"

},
"claim": {
"cta": "Reclamar",
"cta-msg": "¡Reclamá tu certificado en blockchain gratis!",
"opensea-alt": "logo open sea",
"wapp-msg": "Me gustaría mintear el NFT"
},
"share": {
"cta": "Compartir",
"clipboard": "Link copiado!"
}
},
"account": {
Expand All @@ -353,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!"
}
}
}
}
218 changes: 218 additions & 0 deletions src/sections/nfts/nft-item-share.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
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,
IconButton,
Typography,
DialogTitle,
DialogActions,
DialogContent
} 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 { enqueueSnackbar } = useSnackbar()

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}`)
enqueueSnackbar(t('nfts.share.clipboard'), { variant: 'info' })
} 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 (
<Stack spacing={3} sx={{ mb: 10, textAlign: 'center' }}>
<m.div variants={varFade().in}>
<Typography
variant='h3'
sx={{
textAlign: 'center',
maxWidth: 'min(700px, 100%)',
marginTop: '20px',
marginLeft: 'auto',
marginRight: 'auto',
mb: mdUp ? 0 : 5
}}
>
{nftData.metadata.description}
</Typography>
</m.div>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
gap: '20px',
width: '100%',
marginTop: '20px'
}}
>
<Card
sx={{
position: 'relative'
}}
>
<Box sx={{ maxWidth: 400, maxHeight: 400, overflow: 'hidden' }}>
<Image
layout='responsive'
width={200}
height={200}
src={imageUrl}
alt={nftData.metadata.description}
/>
</Box>

{/* Botones flotantes */}
<Box sx={{ position: 'absolute', top: 10, right: 10, display: 'flex', gap: 1 }}>
<m.div variants={varFade().in}>
<IconButton
onClick={() => setOpenShare(true)}
sx={{
backgroundColor: 'white',
'&:hover': { backgroundColor: 'rgba(255,255,255,0.9)' }
}}
>
<Icon icon='ri:share-fill' width={24} />
</IconButton>
</m.div>

<m.button
initial={{ scale: 1 }}
whileHover={{ scale: 1.1, cursor: 'pointer' }}
transition={{ duration: 0.1 }}
onClick={handleOpenOpenSea}
style={{
backgroundColor: 'white',
border: 'none',
borderRadius: '50%',
padding: '8px'
}}
>
<Image
width={24}
height={24}
src='https://storage.googleapis.com/opensea-static/Logomark/Logomark-Blue.svg'
alt={t('nfts.claim.opensea-alt')}
/>
</m.button>
</Box>
</Card>

<m.div variants={varFade().inUp}>
<Button size='large' color='inherit' variant='contained' onClick={handleTriggerShare}>
<Icon icon='ri:share-fill' width={20} style={{ marginRight: 8 }} />{' '}
{t('nfts.share.cta')}
</Button>
</m.div>
</Box>

{/* Diálogo de compartir */}
<Dialog open={openShare} onClose={handleTriggerShare} maxWidth='xs' fullWidth>
<DialogTitle>{t('nfts.share.cta')}</DialogTitle>
<DialogContent>
<Box
sx={{
display: 'grid',
gridTemplateColumns: 'repeat(2, 1fr)',
gap: 2,
pt: 2
}}
>
{socialButtons.map((button) => (
<Button
key={button.name}
onClick={button.action}
variant='outlined'
startIcon={<Icon icon={button.icon} />}
fullWidth
sx={{ justifyContent: 'flex-start' }}
>
{button.name}
</Button>
))}
</Box>
</DialogContent>
<DialogActions>
<Button variant='outlined' color='inherit' onClick={handleTriggerShare}>
{t('common.close')}
</Button>
</DialogActions>
</Dialog>
</Stack>
)
}
Loading

0 comments on commit c4102c3

Please sign in to comment.