diff --git a/examples/buddybook/src/App.tsx b/examples/buddybook/src/App.tsx index 629b6eb..cebe02a 100644 --- a/examples/buddybook/src/App.tsx +++ b/examples/buddybook/src/App.tsx @@ -7,7 +7,7 @@ import { Button } from "@/components/ui/button" import { type LightNode } from "@waku/sdk" import { useWaku } from "@waku/react" import { Loader2 } from "lucide-react" -import { Routes, Route, Navigate, Link, useParams } from 'react-router-dom' +import { Routes, Route, Navigate, Link } from 'react-router-dom' import { BlockPayload, getMessagesFromStore, subscribeToFilter } from './lib/waku' import TelemetryOptIn from './components/TelemetryOptIn'; import TelemetryPage from './components/TelemetryPage'; @@ -117,7 +117,7 @@ function App() { return (
-
+
} /> } /> @@ -132,21 +132,19 @@ function App() { } const Home: React.FC = () => ( -
-

BuddyChain

-
+
+

BuddyChain

+
- -

+

Click the button above to start creating a new chain.

-

+

Welcome to BuddyChain - Create and share your chains!

diff --git a/examples/buddybook/src/components/Chain/SignChain.tsx b/examples/buddybook/src/components/Chain/SignChain.tsx index 773bc8a..49f1c98 100644 --- a/examples/buddybook/src/components/Chain/SignChain.tsx +++ b/examples/buddybook/src/components/Chain/SignChain.tsx @@ -11,10 +11,11 @@ import { v4 as uuidv4 } from 'uuid'; interface SignChainProps { block: BlockPayload; + chainsData: BlockPayload[]; // Add this prop onSuccess: (newBlock: BlockPayload) => void; } -const SignChain: React.FC = ({ block, onSuccess }) => { +const SignChain: React.FC = ({ block, chainsData, onSuccess }) => { const [isOpen, setIsOpen] = useState(false); const [isSigning, setIsSigning] = useState(false); const [error, setError] = useState(null); @@ -25,17 +26,37 @@ const SignChain: React.FC = ({ block, onSuccess }) => { useEffect(() => { if (address) { - const hasAlreadySigned = block.signatures.some(sig => sig.address.toLowerCase() === address.toLowerCase()); + // Check if the address has signed this block or any blocks in the chain + const checkSignatures = (blockToCheck: BlockPayload): boolean => { + // Check current block's signatures + if (blockToCheck.signatures.some( + sig => sig.address.toLowerCase() === address.toLowerCase() + )) { + return true; + } + + // Check parent blocks + const parentBlock = chainsData.find(b => b.blockUUID === blockToCheck.parentBlockUUID); + if (parentBlock && checkSignatures(parentBlock)) { + return true; + } + + // Check child blocks + const childBlocks = chainsData.filter(b => b.parentBlockUUID === blockToCheck.blockUUID); + return childBlocks.some(childBlock => checkSignatures(childBlock)); + }; + + const hasAlreadySigned = checkSignatures(block); setAlreadySigned(hasAlreadySigned); } - }, [address, block.signatures]); + }, [address, block, chainsData]); const { signMessage } = useSignMessage({ mutation: { async onSuccess(signature) { if (!address || !node) return; - // Check if the address has already signed + // Double check signature before proceeding if (block.signatures.some(sig => sig.address.toLowerCase() === address.toLowerCase())) { setError('You have already signed this chain.'); setIsSigning(false); @@ -79,6 +100,7 @@ const SignChain: React.FC = ({ block, onSuccess }) => { }); const handleSign = () => { + // Add an additional check here before signing if (alreadySigned) { setError('You have already signed this chain.'); return; diff --git a/examples/buddybook/src/components/Chain/SignSharedChain.tsx b/examples/buddybook/src/components/Chain/SignSharedChain.tsx index 867786f..a57f6bc 100644 --- a/examples/buddybook/src/components/Chain/SignSharedChain.tsx +++ b/examples/buddybook/src/components/Chain/SignSharedChain.tsx @@ -44,7 +44,11 @@ const SignSharedChain: React.FC = ({ chainsData, onChainUp

{block.title}

{block.description}

- +
); diff --git a/examples/buddybook/src/components/Chain/View/ChainList.tsx b/examples/buddybook/src/components/Chain/View/ChainList.tsx index 39de0c7..c896d72 100644 --- a/examples/buddybook/src/components/Chain/View/ChainList.tsx +++ b/examples/buddybook/src/components/Chain/View/ChainList.tsx @@ -50,7 +50,11 @@ const ChainList: React.FC = ({ chainsData, onChainUpdate, isLoad Block UUID: {block.blockUUID}

- + diff --git a/examples/buddybook/src/components/Header.tsx b/examples/buddybook/src/components/Header.tsx index b2ea92f..1d9c093 100644 --- a/examples/buddybook/src/components/Header.tsx +++ b/examples/buddybook/src/components/Header.tsx @@ -56,69 +56,78 @@ const Header: React.FC = ({ wakuStatus }) => { }; return ( -
-
-
-

BuddyBook

- -
-
-
- Filter: -
+
+
+
+
+

BuddyBook

+
-
- Store: -
+ +
+
+
+ Filter: +
+
+
+ Store: +
+
+
+ +
+ {isWakuLoading ? ( + + ) : wakuError ? ( + Waku Error + ) : ( + + Waku Connections: {connections} + + )} + + {isConnected ? ( +
+ + {ensName || (address ? `${address.slice(0, 6)}...${address.slice(-4)}` : '')} + + +
+ ) : ( + + )} +
- {isWakuLoading ? ( - - ) : wakuError ? ( - Waku Error - ) : ( - - Waku Connections: {connections} - - )} - {isConnected ? ( - <> - - {ensName || (address ? `${address.slice(0, 6)}...${address.slice(-4)}` : '')} - - - - ) : ( - - )}
diff --git a/examples/buddybook/src/components/TelemetryOptIn.tsx b/examples/buddybook/src/components/TelemetryOptIn.tsx index bda4ae0..4222d8a 100644 --- a/examples/buddybook/src/components/TelemetryOptIn.tsx +++ b/examples/buddybook/src/components/TelemetryOptIn.tsx @@ -14,33 +14,50 @@ const PrivacyPolicyOptIn: React.FC = ({ onOptIn }) => { const [showFullPolicy, setShowFullPolicy] = useState(false); return ( -
+
- - Privacy Policy & Data Collection + + Privacy Policy & Data Collection -

- We collect data to improve our services. This data is anonymous and helps us understand how our application is used. You can opt-in or opt-out of this data collection. -

- +
+

+ We collect data to improve our services. This data is anonymous and helps us understand how our application is used. You can opt-in or opt-out of this data collection. +

+ +
- - - + + +
- + - Privacy Policy + Privacy Policy - + - + {privacyPolicy} diff --git a/examples/buddybook/src/components/TelemetryPage.tsx b/examples/buddybook/src/components/TelemetryPage.tsx index 2fdd750..e8c9695 100644 --- a/examples/buddybook/src/components/TelemetryPage.tsx +++ b/examples/buddybook/src/components/TelemetryPage.tsx @@ -23,27 +23,32 @@ const PrivacyPolicyPage: React.FC = () => { }; return ( - - - Privacy Policy Settings + + + Privacy Policy Settings -
-
-

+

+
+

We collect data to improve our services. This data is anonymous and helps us understand how our application is used.

-

- Current status: {privacyPolicyOptIn ? 'Opted In' : 'Opted Out'} -

- +
+

+ Current status: {privacyPolicyOptIn ? 'Opted In' : 'Opted Out'} +

+ +
-

Privacy Policy

- - +

Privacy Policy

+ + {privacyPolicy} diff --git a/examples/buddybook/src/components/ui/card.tsx b/examples/buddybook/src/components/ui/card.tsx index 77e9fb7..94c9736 100644 --- a/examples/buddybook/src/components/ui/card.tsx +++ b/examples/buddybook/src/components/ui/card.tsx @@ -9,7 +9,7 @@ const Card = React.forwardRef<
(({ className, ...props }, ref) => (
)) diff --git a/examples/buddybook/src/index.css b/examples/buddybook/src/index.css index 46947be..1d45b6b 100644 --- a/examples/buddybook/src/index.css +++ b/examples/buddybook/src/index.css @@ -56,11 +56,34 @@ --chart-5: 340 75% 55% } } + @layer base { * { @apply border-border; } body { @apply bg-background text-foreground; + } + .container { + @apply px-4 md:px-6 lg:px-8; } -} \ No newline at end of file + + h1 { + @apply text-2xl md:text-4xl font-bold; + } + + h2 { + @apply text-xl md:text-3xl font-semibold; + } + + h3 { + @apply text-lg md:text-2xl font-semibold; + } + .section { + @apply py-4 md:py-6 lg:py-8; + } + + .card { + @apply p-4 md:p-6; + } +}