Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/app/components/SwapComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import {
formatExpiryTime,
isExpiringSoon,
getStampUsage,
updateHistoryAfterTopUp,
} from './utils';
import { useTimer } from './TimerUtils';

Expand Down Expand Up @@ -907,6 +908,11 @@ const SwapComponent: React.FC = () => {
message: 'Batch Topped Up Successfully',
isSuccess: true,
});

// Update upload history with new expiry date immediately
if (address && topUpBatchId && selectedDays) {
updateHistoryAfterTopUp(topUpBatchId as string, selectedDays, address);
}
// Don't set upload step for top-ups
} else {
try {
Expand Down Expand Up @@ -1128,6 +1134,11 @@ const SwapComponent: React.FC = () => {
message: 'Batch Topped Up Successfully',
isSuccess: true,
});

// Update upload history with new expiry date immediately
if (address && selectedDays) {
updateHistoryAfterTopUp(topUpBatchId, selectedDays, address);
}
} else {
// Calculate the batch ID for new batch creation
const calculatedBatchId = readBatchId(
Expand Down
87 changes: 73 additions & 14 deletions src/app/components/UploadHistorySection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,41 @@ const UploadHistorySection: React.FC<UploadHistoryProps> = ({ address, setShowUp
}
};

const clearExpiredHistory = () => {
if (!address) return;

const now = Date.now();
const expiredCount = history.filter(record => record.expiryDate < now).length;

if (expiredCount === 0) {
window.alert('No expired items to clear.');
return;
}

const confirmed = window.confirm(
`Are you sure you want to clear ${expiredCount} expired item${expiredCount > 1 ? 's' : ''} from your upload history? This action cannot be undone.`
);
if (confirmed) {
// Filter out expired items
const nonExpiredHistory = history.filter(record => record.expiryDate >= now);
setHistory(nonExpiredHistory);

// Update localStorage
const savedHistory = localStorage.getItem('uploadHistory');
if (savedHistory) {
const allHistory: UploadHistory = JSON.parse(savedHistory);
allHistory[address] = nonExpiredHistory;
localStorage.setItem('uploadHistory', JSON.stringify(allHistory));
}
}
};

// Count expired items for button visibility
const expiredCount = React.useMemo(() => {
const now = Date.now();
return history.filter(record => record.expiryDate < now).length;
}, [history]);

const startEditingFilename = (
index: number,
reference: string,
Expand Down Expand Up @@ -1008,8 +1043,12 @@ const UploadHistorySection: React.FC<UploadHistoryProps> = ({ address, setShowUp
</svg>
</label>
)}
{history.length > 0 && (
<button className={styles.clearButton} onClick={clearHistory} title="Clear History">
{expiredCount > 0 && (
<button
className={styles.clearExpiredButton}
onClick={clearExpiredHistory}
title={`Clear ${expiredCount} Expired Item${expiredCount > 1 ? 's' : ''}`}
>
<svg
width="20"
height="20"
Expand All @@ -1020,15 +1059,15 @@ const UploadHistorySection: React.FC<UploadHistoryProps> = ({ address, setShowUp
strokeLinecap="round"
strokeLinejoin="round"
>
<polyline points="3,6 5,6 21,6" />
<path d="m19,6v14a2,2 0 0,1 -2,2H7a2,2 0 0,1 -2,-2V6m3,0V4a2,2 0 0,1 2,-2h4a2,2 0 0,1 2,2v2" />
<line x1="10" y1="11" x2="10" y2="17" />
<line x1="14" y1="11" x2="14" y2="17" />
<path d="M5 22h14" />
<path d="M5 2h14" />
<path d="M17 22v-4.172a2 2 0 0 0-.586-1.414L12 12l-4.414 4.414A2 2 0 0 0 7 17.828V22" />
<path d="M7 2v4.172a2 2 0 0 0 .586 1.414L12 12l4.414-4.414A2 2 0 0 0 17 6.172V2" />
</svg>
</button>
)}
{address && (
<div className={styles.ensInfo}>
{history.length > 0 && (
<button className={styles.clearButton} onClick={clearHistory} title="Clear History">
<svg
width="20"
height="20"
Expand All @@ -1039,13 +1078,12 @@ const UploadHistorySection: React.FC<UploadHistoryProps> = ({ address, setShowUp
strokeLinecap="round"
strokeLinejoin="round"
>
<circle cx="12" cy="12" r="10" />
<path d="M12 2L2 7v10c0 5.55 3.84 10 9 10s9-4.45 9-10V7L12 2z" />
<polyline points="3,6 5,6 21,6" />
<path d="m19,6v14a2,2 0 0,1 -2,2H7a2,2 0 0,1 -2,-2V6m3,0V4a2,2 0 0,1 2,-2h4a2,2 0 0,1 2,2v2" />
<line x1="10" y1="11" x2="10" y2="17" />
<line x1="14" y1="11" x2="14" y2="17" />
</svg>
<span className={styles.ensTooltip}>
Click on ENS button to link reference to your ENS domain
</span>
</div>
</button>
)}
</div>
</div>
Expand Down Expand Up @@ -1131,6 +1169,27 @@ const UploadHistorySection: React.FC<UploadHistoryProps> = ({ address, setShowUp
</div>
)}

{/* ENS Note */}
{address && history.length > 0 && (
<div className={styles.ensNote}>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<circle cx="12" cy="12" r="10" />
<line x1="12" y1="16" x2="12" y2="12" />
<line x1="12" y1="8" x2="12.01" y2="8" />
</svg>
<span>Click on ENS button to link reference to your ENS domain</span>
</div>
)}

{!address ? (
<div className={styles.emptyState}>Connect wallet to check upload history</div>
) : history.length === 0 ? (
Expand Down
40 changes: 31 additions & 9 deletions src/app/components/css/UploadHistorySection.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,25 @@
color: #dc3545;
}

.clearExpiredButton {
background-color: transparent;
border: 1px solid #30363d;
border-radius: 6px;
color: #8b949e;
cursor: pointer;
padding: 8px;
transition: all 0.2s ease;
display: flex;
align-items: center;
justify-content: center;
}

.clearExpiredButton:hover {
background-color: rgba(245, 158, 11, 0.2);
border-color: #f59e0b;
color: #f59e0b;
}

.hiddenInput {
display: none;
}
Expand Down Expand Up @@ -410,23 +429,26 @@
}

/* ENS Integration Styles */
.ensInfo {
.ensNote {
display: flex;
align-items: center;
gap: 6px;
gap: 8px;
padding: 10px 14px;
margin-bottom: 12px;
background-color: rgba(59, 130, 246, 0.1);
border: 1px solid rgba(59, 130, 246, 0.25);
border-radius: 6px;
color: #8b949e;
position: relative;
margin-left: 8px;
font-size: 13px;
}

.ensInfo svg {
.ensNote svg {
color: #3b82f6;
flex-shrink: 0;
}

.ensTooltip {
font-size: 12px;
color: #8b949e;
font-weight: 500;
.ensNote span {
color: #c9d1d9;
}

.ensButton {
Expand Down
70 changes: 70 additions & 0 deletions src/app/components/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,76 @@ export const fetchStampInfo = async (batchId: string, beeApiUrl: string): Promis
}
};

/**
* Update upload history expiry dates for a specific stamp after top-up
* @param stampId The stamp batch ID that was topped up
* @param additionalDays The number of days added by the top-up
* @param address The wallet address whose history to update
* @returns boolean True if history was updated, false otherwise
*/
export const updateHistoryAfterTopUp = (
stampId: string,
additionalDays: number,
address: string
): boolean => {
try {
console.log(`🔄 Updating upload history for topped-up stamp: ${stampId} (+${additionalDays} days)`);

// Get the upload history from localStorage
const savedHistory = localStorage.getItem('uploadHistory');
if (!savedHistory) {
console.log('No upload history found');
return false;
}

const allHistory = JSON.parse(savedHistory);
const addressHistory = allHistory[address];

if (!addressHistory || addressHistory.length === 0) {
console.log('No upload history found for this address');
return false;
}

// Format stamp ID for comparison (remove 0x prefix if present)
const formattedStampId = stampId.startsWith('0x') ? stampId.slice(2) : stampId;

// Calculate additional milliseconds
const additionalMs = additionalDays * 24 * 60 * 60 * 1000;

// Update all records with this stamp ID
let updatedCount = 0;
const updatedHistory = addressHistory.map((record: any) => {
// Format record's stampId for comparison
const recordStampId = record.stampId?.startsWith('0x')
? record.stampId.slice(2)
: record.stampId;

if (recordStampId?.toLowerCase() === formattedStampId.toLowerCase()) {
updatedCount++;
// Add the additional days to the existing expiry date
const newExpiryDate = record.expiryDate + additionalMs;
console.log(`📅 Updated expiry: ${new Date(newExpiryDate).toLocaleDateString()}`);
return { ...record, expiryDate: newExpiryDate };
}
return record;
});

if (updatedCount > 0) {
// Save updated history
allHistory[address] = updatedHistory;
localStorage.setItem('uploadHistory', JSON.stringify(allHistory));
console.log(`✅ Updated ${updatedCount} history record(s) with new expiry date`);
return true;
} else {
console.log('No matching history records found for this stamp');
return false;
}
} catch (error) {
console.error('Error updating history after top-up:', error);
return false;
}
};

/**
* Format TTL (Time To Live) in seconds to a human-readable string
* Shows hours/minutes for < 1 day, otherwise shows days
Expand Down