Skip to content

Commit a86fe00

Browse files
fix: mock up-provider
1 parent 0e4ba9a commit a86fe00

File tree

3 files changed

+157
-95
lines changed

3 files changed

+157
-95
lines changed

app/page.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"use client";
22

3-
import { UpProvider } from "@/components/upProvider";
3+
// Temporarily use mock provider for local testing
4+
// import { UpProvider } from "@/components/upProvider";
5+
import { UpProvider } from "@/components/mockUpProvider";
46
import { ApparelSizeManager } from "@/components/ApparelSizeManager";
57
import { useState, useEffect } from "react";
68

components/ApparelSizeManager.tsx

Lines changed: 66 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515

1616
import { useCallback, useEffect, useState } from 'react';
1717
import { ERC725 } from '@erc725/erc725.js';
18-
import { useUpProvider } from './upProvider';
18+
// Temporarily use mock provider for local testing
19+
// import { useUpProvider } from './upProvider';
20+
import { useUpProvider } from './mockUpProvider';
1921
import { encodeFunctionData, keccak256, toHex } from 'viem';
2022

2123
// Generate the key for ApparelSize using keccak256
@@ -63,7 +65,7 @@ const MOCK_SHOES = [
6365
size: '8',
6466
price: '220 LYX',
6567
description: 'Timeless leather shoes for formal occasions',
66-
image: 'https://images.unsplash.com/photo-1614252369475-531eba835eb1?w=400&h=300&fit=crop&crop=center'
68+
image: 'https://images.unsplash.com/photo-1542291026-7eec264c27ff?w=400&h=300&fit=crop&crop=center'
6769
},
6870
{
6971
id: 3,
@@ -99,7 +101,7 @@ const MOCK_SHOES = [
99101
size: '10',
100102
price: '200 LYX',
101103
description: 'Durable outdoor hiking shoes',
102-
image: 'https://images.unsplash.com/photo-1478827536114-da961b7f86d2?w=400&h=300&fit=crop&crop=center'
104+
image: 'https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a?w=400&h=300&fit=crop&crop=center'
103105
},
104106
{
105107
id: 7,
@@ -131,7 +133,7 @@ const MOCK_APPAREL = [
131133
price: '89 LYX',
132134
description: 'Comfortable cotton blend hoodie with modern fit',
133135
category: 'Hoodies',
134-
image: 'https://images.unsplash.com/photo-1620799140408-edc7d8697a2f?w=400&h=300&fit=crop&crop=center'
136+
image: 'https://images.unsplash.com/photo-1556821840-3a63f95609a7?w=400&h=300&fit=crop&crop=center'
135137
},
136138
{
137139
id: 2,
@@ -171,7 +173,7 @@ const MOCK_APPAREL = [
171173
price: '28 LYX',
172174
description: 'Moisture-wicking athletic tank top',
173175
category: 'Activewear',
174-
image: 'https://images.unsplash.com/photo-1575987116913-e96e7d490a8a?w=400&h=300&fit=crop&crop=center'
176+
image: 'https://images.unsplash.com/photo-1571945153237-4929e783af4a?w=400&h=300&fit=crop&crop=center'
175177
},
176178
{
177179
id: 6,
@@ -222,14 +224,12 @@ export function ApparelSizeManager() {
222224

223225
setIsLoading(true);
224226
try {
225-
const rpcEndpoint = chainId === 42 ? RPC_ENDPOINT_MAINNET : RPC_ENDPOINT_TESTNET;
226-
const erc725 = new ERC725(APPAREL_SIZE_SCHEMA, accounts[0], rpcEndpoint);
227-
228-
const result = await erc725.getData('ApparelSize');
227+
// For local testing, use localStorage instead of blockchain
228+
const storedData = localStorage.getItem('apparelSizes');
229229

230-
if (result.value && typeof result.value === 'string') {
230+
if (storedData) {
231231
try {
232-
const apparelData: ApparelData = JSON.parse(result.value);
232+
const apparelData: ApparelData = JSON.parse(storedData);
233233
const validData = {
234234
shoeSizes: Array.isArray(apparelData.shoeSizes) ? apparelData.shoeSizes : [],
235235
apparelSizes: Array.isArray(apparelData.apparelSizes) ? apparelData.apparelSizes : []
@@ -298,49 +298,14 @@ export function ApparelSizeManager() {
298298
const jsonData = JSON.stringify(apparelData);
299299

300300
console.log('Saving apparel data:', jsonData);
301-
console.log('Schema:', APPAREL_SIZE_SCHEMA);
302-
303-
const rpcEndpoint = chainId === 42 ? RPC_ENDPOINT_MAINNET : RPC_ENDPOINT_TESTNET;
304-
const erc725 = new ERC725(APPAREL_SIZE_SCHEMA, accounts[0], rpcEndpoint);
301+
302+
// For local testing, save to localStorage instead of blockchain
303+
localStorage.setItem('apparelSizes', jsonData);
304+
305+
// Simulate transaction delay
306+
await new Promise(resolve => setTimeout(resolve, 1000));
305307

306-
// Encode the apparel data
307-
const encodedData = erc725.encodeData([
308-
{
309-
keyName: 'ApparelSize',
310-
value: jsonData,
311-
}
312-
]);
313-
314-
console.log('Encoded data:', encodedData);
315-
316-
// Create setData function call using viem
317-
const setDataCalldata = encodeFunctionData({
318-
abi: [
319-
{
320-
name: 'setData',
321-
type: 'function',
322-
inputs: [
323-
{ name: 'dataKey', type: 'bytes32' },
324-
{ name: 'dataValue', type: 'bytes' }
325-
],
326-
outputs: [],
327-
stateMutability: 'nonpayable'
328-
}
329-
],
330-
functionName: 'setData',
331-
args: [encodedData.keys[0] as `0x${string}`, encodedData.values[0] as `0x${string}`]
332-
});
333-
334-
// Execute setData transaction via Universal Profile
335-
const tx = await client!.sendTransaction({
336-
account: accounts[0] as `0x${string}`,
337-
to: accounts[0] as `0x${string}`,
338-
data: setDataCalldata,
339-
value: BigInt(0),
340-
chain: client!.chain,
341-
});
342-
343-
console.log('Apparel data saved successfully:', tx);
308+
console.log('Apparel data saved successfully to localStorage');
344309

345310
// Update state and switch to marketplace view
346311
setCurrentApparelData(apparelData);
@@ -361,33 +326,11 @@ export function ApparelSizeManager() {
361326

362327
} catch (error: any) {
363328
console.error('Error saving apparel data:', error);
364-
365-
// Detailed error handling for debugging
366-
if (error?.message) {
367-
console.error('Error message:', error.message);
368-
console.error('Error code:', error.code);
369-
console.error('Full error:', error);
370-
}
371-
372-
let errorMessage = 'Failed to save apparel data';
373-
374-
if (error?.message) {
375-
if (error.message.includes('User rejected') || error.message.includes('user rejected')) {
376-
errorMessage = 'Transaction was cancelled by user';
377-
} else if (error.message.includes('insufficient funds')) {
378-
errorMessage = 'Insufficient LYX balance for transaction';
379-
} else if (error.message.includes('execution reverted')) {
380-
errorMessage = 'Transaction failed - this might be a permissions issue. Make sure your wallet has the necessary permissions to modify the Universal Profile.';
381-
} else {
382-
errorMessage = `Transaction failed: ${error.message}`;
383-
}
384-
}
385-
386-
alert(errorMessage);
329+
alert('Failed to save apparel data');
387330
} finally {
388331
setIsSaving(false);
389332
}
390-
}, [client, walletConnected, accounts, newShoeSizes, selectedApparelSizes, chainId]);
333+
}, [client, walletConnected, accounts, newShoeSizes, selectedApparelSizes]);
391334

392335
useEffect(() => {
393336
fetchApparelData();
@@ -415,20 +358,33 @@ export function ApparelSizeManager() {
415358
setCurrentView(view);
416359
};
417360

418-
if (!walletConnected) {
419-
return (
420-
<div className="w-full bg-white/90 backdrop-blur-sm rounded-xl p-4 text-center">
421-
<p className="text-sm text-gray-600">Please connect your Universal Profile to manage your apparel preferences.</p>
422-
</div>
423-
);
424-
}
361+
// For local testing, always show the component
362+
// if (!walletConnected) {
363+
// return (
364+
// <div className="w-full bg-white/90 backdrop-blur-sm rounded-xl p-4 text-center">
365+
// <p className="text-sm text-gray-600">Please connect your Universal Profile to manage your apparel preferences.</p>
366+
// </div>
367+
// );
368+
// }
425369

426370
return (
427371
<div className="w-full bg-white/90 backdrop-blur-sm rounded-xl p-4">
428372
<div className="flex justify-between items-center mb-4">
429373

430374
{/* Navigation buttons */}
431375
<div className="flex gap-1">
376+
{/* Clear data button for testing */}
377+
<button
378+
onClick={() => {
379+
localStorage.removeItem('apparelSizes');
380+
window.location.reload();
381+
}}
382+
className="flex items-center gap-1 px-2 py-1 text-xs font-medium text-red-600 hover:text-red-800 hover:bg-red-50 rounded-md transition-colors"
383+
title="Clear stored data (testing only)"
384+
>
385+
<lukso-icon name="cross-outline" size="small" color="red-60"></lukso-icon>
386+
Clear Data
387+
</button>
432388
{currentView === 'marketplace' && (
433389
<button
434390
onClick={() => handleViewChange('connected-user')}
@@ -530,16 +486,32 @@ export function ApparelSizeManager() {
530486
</div>
531487
</div>
532488

533-
<lukso-button
534-
onClick={saveApparelData}
535-
variant="primary"
536-
size="small"
537-
isLoading={isSaving}
538-
disabled={(!newShoeSizes.trim() && selectedApparelSizes.length === 0) || isLoading}
539-
is-full-width
540-
>
541-
{isSaving ? 'Saving...' : 'Save Preferences'}
542-
</lukso-button>
489+
<div className="flex gap-2">
490+
<lukso-button
491+
onClick={saveApparelData}
492+
variant="primary"
493+
size="small"
494+
isLoading={isSaving}
495+
disabled={(!newShoeSizes.trim() && selectedApparelSizes.length === 0) || isLoading}
496+
is-full-width
497+
>
498+
{isSaving ? 'Saving...' : 'Save Preferences'}
499+
</lukso-button>
500+
501+
<lukso-button
502+
onClick={() => {
503+
setCurrentView('marketplace');
504+
// Show all items when browsing without preferences
505+
setFilteredShoes(MOCK_SHOES);
506+
setFilteredApparel(MOCK_APPAREL);
507+
}}
508+
variant="secondary"
509+
size="small"
510+
is-full-width
511+
>
512+
Browse Marketplace
513+
</lukso-button>
514+
</div>
543515
</div>
544516

545517
{/* Information Box */}

components/mockUpProvider.tsx

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/**
2+
* @component MockUpProvider
3+
* @description Mock context provider for local testing without wallet connection
4+
*/
5+
"use client";
6+
7+
import {
8+
createContext,
9+
useContext,
10+
useState,
11+
type ReactNode,
12+
useMemo,
13+
} from "react";
14+
import { createWalletClient, http } from "viem";
15+
import { luksoTestnet } from "viem/chains";
16+
17+
interface UpProviderContext {
18+
provider: any;
19+
client: ReturnType<typeof createWalletClient> | null;
20+
chainId: number;
21+
accounts: Array<`0x${string}`>;
22+
contextAccounts: Array<`0x${string}`>;
23+
walletConnected: boolean;
24+
selectedAddress: `0x${string}` | null;
25+
setSelectedAddress: (address: `0x${string}` | null) => void;
26+
isSearching: boolean;
27+
setIsSearching: (isSearching: boolean) => void;
28+
}
29+
30+
const UpContext = createContext<UpProviderContext | undefined>(undefined);
31+
32+
export function useUpProvider() {
33+
const context = useContext(UpContext);
34+
if (!context) {
35+
throw new Error("useUpProvider must be used within a UpProvider");
36+
}
37+
return context;
38+
}
39+
40+
interface UpProviderProps {
41+
children: ReactNode;
42+
}
43+
44+
export function UpProvider({ children }: UpProviderProps) {
45+
const [selectedAddress, setSelectedAddress] = useState<`0x${string}` | null>(null);
46+
const [isSearching, setIsSearching] = useState(false);
47+
48+
// Mock values for local testing
49+
const mockAccounts: Array<`0x${string}`> = ["0x1234567890123456789012345678901234567890"];
50+
const mockChainId = 4201; // Lukso testnet
51+
const mockWalletConnected = true; // Always connected for testing
52+
53+
// Create a mock client
54+
const client = useMemo(() => {
55+
return createWalletClient({
56+
chain: luksoTestnet,
57+
transport: http(),
58+
});
59+
}, []);
60+
61+
const data = useMemo(() => {
62+
return {
63+
provider: null,
64+
client,
65+
chainId: mockChainId,
66+
readClient: client,
67+
accounts: mockAccounts,
68+
contextAccounts: mockAccounts,
69+
walletConnected: mockWalletConnected,
70+
selectedAddress,
71+
setSelectedAddress,
72+
isSearching,
73+
setIsSearching,
74+
};
75+
}, [
76+
client,
77+
selectedAddress,
78+
isSearching,
79+
]);
80+
81+
return (
82+
<UpContext.Provider value={data}>
83+
<div className="min-h-screen flex items-center justify-center">
84+
{children}
85+
</div>
86+
</UpContext.Provider>
87+
);
88+
}

0 commit comments

Comments
 (0)