mirror of
https://github.com/ChanX21/Sigillum
synced 2026-04-21 15:47:55 +00:00
commit
683f8493ec
5 changed files with 67 additions and 18 deletions
|
|
@ -13,8 +13,8 @@ export default function Upload() {
|
|||
<>
|
||||
<Header />
|
||||
<main className="flex flex-col w-full min-h-screen pt-24 px-4 md:px-10 mb-12 ">
|
||||
{step == 0 && <ImageUploadShowcase setStep={setStep} setStepLoading={setStepLoading}/>}
|
||||
{step == 1 && <NftMintedDetails setStep={setStep} />}
|
||||
{step == 0 && <ImageUploadShowcase setStep={setStep} setStepLoading={setStepLoading} />}
|
||||
{step == 1 && <NftMintedDetails step={step} setStep={setStep} />}
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { Button } from "../ui/button";
|
|||
import { toast } from "sonner";
|
||||
import { useEffect, useState } from "react";
|
||||
import { IoMdCloudUpload } from "react-icons/io";
|
||||
import { CheckCircle2, Shield, UploadCloud } from "lucide-react";
|
||||
import { AlertCircle, CheckCircle2, Shield, UploadCloud } from "lucide-react";
|
||||
import { initSocket } from "@/lib/socket";
|
||||
import { GoDownload } from "react-icons/go";
|
||||
import { Card } from "../ui/card";
|
||||
|
|
@ -14,7 +14,8 @@ import { GiWalrusHead } from "react-icons/gi";
|
|||
import OptimizedImage from "../shared/OptimizedImage";
|
||||
|
||||
interface NFTDetailsProps {
|
||||
compact?: boolean;
|
||||
step: number;
|
||||
compact?: boolean;
|
||||
setStep: (step: number) => void;
|
||||
}
|
||||
const statusSteps = [
|
||||
|
|
@ -41,7 +42,7 @@ const statusSteps = [
|
|||
label: "Tokenizing Image",
|
||||
description: "Tokenizing the image as an NFT on the blockchain.",
|
||||
icon: <Shield className="w-8 h-8" />,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "softListed",
|
||||
label: "Soft Listing on Marketplace",
|
||||
|
|
@ -57,12 +58,13 @@ const stepProgress = {
|
|||
"image:softListed": 100,
|
||||
};
|
||||
|
||||
export const NFTDetails = ({ compact = false, setStep }: NFTDetailsProps) => {
|
||||
export const NFTDetails = ({ step, compact = false, setStep }: NFTDetailsProps) => {
|
||||
const { sessionId: token } = useImageAuthStore() as AuthState;
|
||||
const error = useImageAuthStore((s) => s.error);
|
||||
const [status, setStatus] = useState('')
|
||||
const [statusStep, setStatusStep] = useState(0)
|
||||
const [completed, setCompleted] = useState<boolean>(false);
|
||||
const [requestFailed, setRequestFailed] = useState(false)
|
||||
const [progress, setProgress] = useState(0);
|
||||
const [details, setDetails] = useState<
|
||||
{ label: string; value: string | undefined }[]
|
||||
|
|
@ -123,6 +125,14 @@ export const NFTDetails = ({ compact = false, setStep }: NFTDetailsProps) => {
|
|||
return [...prev, newDetail];
|
||||
});
|
||||
});
|
||||
socket.on("image:failed", (data) => {
|
||||
console.log("Failed: ", data?.message)
|
||||
setRequestFailed(true)
|
||||
handleProgress("image:authenticate")
|
||||
setStatusStep(0)
|
||||
useImageAuthStore.getState().setError(null)
|
||||
socket.disconnect();
|
||||
});
|
||||
|
||||
socket.on("image:uploaded", (data) => {
|
||||
handleProgress("image:uploaded")
|
||||
|
|
@ -182,6 +192,11 @@ export const NFTDetails = ({ compact = false, setStep }: NFTDetailsProps) => {
|
|||
}
|
||||
}, [error])
|
||||
|
||||
useEffect(() => {
|
||||
setRequestFailed(false);
|
||||
}, [step]);
|
||||
|
||||
|
||||
const handleCopy = async (text: string, label: string) => {
|
||||
if (!text) return;
|
||||
await navigator.clipboard.writeText(text);
|
||||
|
|
@ -195,8 +210,35 @@ export const NFTDetails = ({ compact = false, setStep }: NFTDetailsProps) => {
|
|||
link.target = "_blank"
|
||||
link.click();
|
||||
};
|
||||
if (requestFailed) {
|
||||
return (
|
||||
<Card className="flex md:min-h-[30vh] flex-col items-center justify-center md:max-w-[30%] px-10 py-16 relative">
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.div
|
||||
key={status}
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -20 }}
|
||||
transition={{ duration: 0.4 }}
|
||||
className="flex flex-col items-center text-center"
|
||||
>
|
||||
<div className="relative w-20 h-20">
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<AlertCircle className="w-16 h-16" />
|
||||
</div>
|
||||
</div>
|
||||
<h3 className="text-lg font-medium mt-6 mb-2">Whoops, something broke.</h3>
|
||||
<p className="text-[#616161] text-center">Hang tight — Walrus will be back in a bit!</p>
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
<Button onClick={() => {
|
||||
setStep(0)
|
||||
}}>Try Again</Button>
|
||||
</Card >
|
||||
)
|
||||
}
|
||||
|
||||
return !completed ? (
|
||||
return !completed && !requestFailed ? (
|
||||
<Card className="flex md:min-h-[60vh] flex-col items-center justify-center md:max-w-[30%] px-10 py-16 relative">
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.div
|
||||
|
|
@ -226,7 +268,7 @@ export const NFTDetails = ({ compact = false, setStep }: NFTDetailsProps) => {
|
|||
/>
|
||||
</motion.div>
|
||||
</Card >
|
||||
) : (
|
||||
) : !requestFailed && (
|
||||
<>
|
||||
<div className="w-full max-w-4xl border border-gray-300 rounded-lg shadow-sm p-0 flex flex-col md:flex-row bg-white mt-2">
|
||||
<div className="flex flex-col items-start w-full md:w-[55%] p-8 pb-4">
|
||||
|
|
|
|||
|
|
@ -7,8 +7,10 @@ import { AuthState, useImageAuthStore } from "@/store/useImageAuthStore";
|
|||
import { NFTDetails } from "./NFTDetails";
|
||||
|
||||
export function NftMintedDetails({
|
||||
step,
|
||||
setStep,
|
||||
}: {
|
||||
step:number;
|
||||
setStep: (step: number) => void;
|
||||
}) {
|
||||
const { result } = useImageAuthStore() as AuthState
|
||||
|
|
@ -29,7 +31,7 @@ export function NftMintedDetails({
|
|||
</div>
|
||||
|
||||
{/* NFT Details */}
|
||||
<NFTDetails setStep={setStep}/>
|
||||
<NFTDetails step={step} setStep={setStep}/>
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ export default function NftAuctionCard({ nft }: NFTCardFeaturedProps) {
|
|||
/>
|
||||
{/* Timer overlay */}
|
||||
<div className="absolute bottom-4 left-1/2 transform -translate-x-1/2 w-[160px] h-[40px] rounded-[16px] border border-white/30 bg-white/30 shadow-[0_4px_30px_rgba(0,0,0,0.1)] backdrop-blur-[5px] flex items-center justify-center">
|
||||
<span className="text-white text-xs font-semibold">
|
||||
<span className="text-white text-xs font-semibold mix-blend-difference">
|
||||
{timeRemaining === "No deadline"
|
||||
? "loading..."
|
||||
: timeRemaining}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Button } from '@/components/ui/button'
|
||||
import { ChevronRight, Clock, Download, FileWarning, History, Share2, Shield, User, X, Check, Copy } from 'lucide-react'
|
||||
import { ChevronRight, Clock, Download, FileWarning, History, Share2, Shield, User, X, Check, Copy, View, ExternalLink } from 'lucide-react'
|
||||
import Image from 'next/image'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { motion } from "framer-motion"
|
||||
|
|
@ -11,6 +11,7 @@ import BeforeAfterSlide from './BeforeAfterSlide'
|
|||
import axios from 'axios'
|
||||
import { UserAvatar } from './UserAvatar'
|
||||
import { displayNftEvents } from '@/utils/blockchainServices'
|
||||
import Link from 'next/link'
|
||||
|
||||
interface VerificationProps {
|
||||
image: string | null
|
||||
|
|
@ -86,14 +87,14 @@ const Verification = ({ image, verificationError, verificationData, isVerifying,
|
|||
|
||||
return response.data
|
||||
}
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (verificationData && verificationData.verifications) {
|
||||
console.log(verificationData)
|
||||
fetchMetadata().then((res) => {
|
||||
setAuthenticImage(res.image)
|
||||
displayNftEvents(verificationData.verifications[0].blockchain.tokenId).then(res => {
|
||||
|
||||
|
||||
setProvenance(res)
|
||||
})
|
||||
}).catch(err => {
|
||||
|
|
@ -298,14 +299,18 @@ const Verification = ({ image, verificationError, verificationData, isVerifying,
|
|||
</div>
|
||||
|
||||
<div className="flex gap-4 pt-4 border-t border-[#f1f3f5]">
|
||||
<Button className="md:flex-1 w-[50%] px-3 bg-[#000] hover:bg-gray-950 rounded-none text-white gap-2 md:py-6 py-3">
|
||||
<Download className="w-4 h-4" />
|
||||
Download Report
|
||||
</Button>
|
||||
<Button variant="outline" className="md:flex-1 w-[50%] px-3 gap-2 md:py-6 py-3 border-[#000] text-[#000] rounded-none">
|
||||
<Link href={`https://sigillum.digital/detail/${verificationData.verifications[0]._id}`} target='_blank' className='w-[50%] flex'>
|
||||
<Button className="md:flex-1 px-3 bg-[#000] hover:bg-gray-950 rounded-none text-white gap-2 md:py-6 py-3 border border-black">
|
||||
<ExternalLink className="w-4 h-4" />
|
||||
View Lisitng
|
||||
</Button>
|
||||
</Link>
|
||||
|
||||
<Button variant="outline" className="md:flex-1 w-[50%] px-3 gap-2 md:py-6 py-3 border-[#000] text-[#000] rounded-none ">
|
||||
<Share2 className="w-4 h-4" />
|
||||
Share Results
|
||||
</Button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
) : verificationError ? (
|
||||
|
|
|
|||
Loading…
Reference in a new issue