mirror of
https://github.com/rangermix/TwitchDropsMiner.git
synced 2026-06-02 10:29:37 +00:00
feat: add account linking status badges to inventory campaign cards
Add visual indicators showing account linking status for each campaign in the inventory tab. Campaigns now display either a "LINKED" (green) or "NOT LINKED" (orange) badge in the top right corner of each card. For unlinked campaigns, both the badge and a "Link Account" button provide direct access to the Twitch account linking page. Backend changes: - Add campaign_url property to DropsCampaign model - Include both campaign_url and link_url in inventory API response Frontend changes: - Add LINKED/NOT LINKED badges positioned at top right of campaign cards - Add "Link Account" button for unlinked campaigns - Style badges with subtle green for linked and prominent orange for not linked - Make NOT LINKED badge clickable to open account linking page 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -28,6 +28,7 @@ class DropsCampaign:
|
||||
def __init__(self, twitch: Twitch, data: JsonType, claimed_benefits: dict[str, datetime]):
|
||||
self._twitch: Twitch = twitch
|
||||
self.id: str = data["id"]
|
||||
self.campaign_url: str = f"https://www.twitch.tv/drops/campaigns?dropID={self.id}"
|
||||
self.name: str = data["name"]
|
||||
self.game: Game = Game(data["game"])
|
||||
self.linked: bool = data["self"]["isAccountConnected"]
|
||||
|
||||
@@ -75,7 +75,8 @@ class InventoryManager:
|
||||
"name": campaign.name,
|
||||
"game_name": campaign.game.name,
|
||||
"image_url": image_url,
|
||||
"link_url": f"https://www.twitch.tv/drops/campaigns?dropID={campaign.id}",
|
||||
"campaign_url": campaign.campaign_url,
|
||||
"link_url": campaign.link_url,
|
||||
"starts_at": campaign.starts_at.isoformat(),
|
||||
"ends_at": campaign.ends_at.isoformat(),
|
||||
"linked": campaign.linked,
|
||||
|
||||
@@ -800,16 +800,26 @@ function renderInventory() {
|
||||
`;
|
||||
}).join('');
|
||||
|
||||
// Make campaign name clickable if link_url is available
|
||||
const campaignNameHtml = campaign.link_url
|
||||
? `<a href="${campaign.link_url}" target="_blank" rel="noopener noreferrer" class="campaign-name-link">${campaign.name} <span class="external-link-icon">🔗</span></a>`
|
||||
: `<div class="campaign-name">${campaign.name}</div>`;
|
||||
const campaignNameHtml = `<a href="${campaign.campaign_url}" target="_blank" rel="noopener noreferrer" class="campaign-name-link">${campaign.name} <span class="external-link-icon">🔗</span></a>`
|
||||
|
||||
// Add LINKED or NOT LINKED badge
|
||||
const linkStatusBadgeHtml = campaign.linked
|
||||
? `<span class="campaign-badge linked" title="Account is linked">LINKED</span>`
|
||||
: `<span class="campaign-badge not-linked" onclick="window.open('${campaign.link_url}', '_blank')" title="Click to link your account">NOT LINKED</span>`;
|
||||
|
||||
const linkAccountButtonHtml = !campaign.linked && campaign.link_url
|
||||
? `<button class="link-account-btn" onclick="window.open('${campaign.link_url}', '_blank')">Link Account</button>`
|
||||
: '';
|
||||
|
||||
const claimedCountText = t.gui?.inventory?.claimed_drops || 'claimed';
|
||||
card.innerHTML = `
|
||||
<div class="campaign-header">
|
||||
<div class="campaign-game">${campaign.game_name}</div>
|
||||
<div class="campaign-game">
|
||||
${campaign.game_name}
|
||||
${linkStatusBadgeHtml}
|
||||
</div>
|
||||
${campaignNameHtml}
|
||||
${linkAccountButtonHtml}
|
||||
</div>
|
||||
<div class="campaign-status">
|
||||
<span>${statusText}</span>
|
||||
|
||||
@@ -609,6 +609,7 @@ header h1 {
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.campaign-header {
|
||||
@@ -647,6 +648,63 @@ header h1 {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.campaign-badge {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
padding: 4px 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.campaign-badge.linked {
|
||||
background: rgba(0, 200, 83, 0.15);
|
||||
color: var(--success-color);
|
||||
border: 1px solid rgba(0, 200, 83, 0.3);
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.campaign-badge.not-linked {
|
||||
background: var(--warning-color);
|
||||
color: white;
|
||||
box-shadow: 0 2px 4px rgba(255, 167, 38, 0.3);
|
||||
}
|
||||
|
||||
.campaign-badge.not-linked:hover {
|
||||
background: #ff9800;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 3px 6px rgba(255, 167, 38, 0.4);
|
||||
}
|
||||
|
||||
.link-account-btn {
|
||||
margin-top: 8px;
|
||||
padding: 8px 16px;
|
||||
background: var(--warning-color);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
box-shadow: 0 2px 4px rgba(255, 167, 38, 0.3);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.link-account-btn:hover {
|
||||
background: #ff9800;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 3px 6px rgba(255, 167, 38, 0.4);
|
||||
}
|
||||
|
||||
.link-account-btn:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 1px 2px rgba(255, 167, 38, 0.3);
|
||||
}
|
||||
|
||||
.campaign-status {
|
||||
padding: 10px 15px;
|
||||
font-size: 12px;
|
||||
|
||||
Reference in New Issue
Block a user