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
5 changes: 3 additions & 2 deletions webapp/src/components/app-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Button as SolanaButton } from '@solana/design-system';
import { Button } from '@/components/ui/button';
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog';
import React from 'react';
Expand Down Expand Up @@ -27,9 +28,9 @@ export function AppModal({
<div className="grid gap-4 py-4">{children}</div>
<DialogFooter>
{submit ? (
<Button type="submit" onClick={submit} disabled={submitDisabled}>
<SolanaButton type="submit" onClick={submit} disabled={submitDisabled}>
{submitLabel || 'Save'}
</Button>
</SolanaButton>
) : null}
</DialogFooter>
</DialogContent>
Expand Down
31 changes: 19 additions & 12 deletions webapp/src/components/delegation/active-delegations.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import { RefreshCw, FileX, Coins, ShieldAlert, Power, Trash2 } from 'lucide-react';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@solana/design-system';
import {
Button as SolanaButton,
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
TextInput,
} from '@solana/design-system';
import { Button } from '@/components/ui/button';
import {
Dialog,
Expand Down Expand Up @@ -212,12 +221,11 @@ function TransferDelegationButton({ delegation, tokenMint, disabled, blockTime }
<div className="py-4 space-y-4">
<div className="space-y-2">
<label className="text-sm font-medium">Amount (USDC)</label>
<input
<TextInput
type="number"
value={amount}
onChange={e => setAmount(e.target.value)}
placeholder="0.00"
className="w-full px-3 py-2 rounded-md border border-input bg-background text-sm"
/>
<p className="text-xs text-muted-foreground">Available: {availableAmount} USDC</p>
</div>
Expand All @@ -232,13 +240,13 @@ function TransferDelegationButton({ delegation, tokenMint, disabled, blockTime }
<Button variant="outline" onClick={() => setOpen(false)}>
Cancel
</Button>
<Button
<SolanaButton
onClick={handleTransfer}
disabled={isPending || !amount || parseFloat(amount) <= 0}
className="bg-green-600 hover:bg-green-700"
loading={isPending}
>
{isPending ? 'Transferring...' : 'Transfer'}
</Button>
Transfer
</SolanaButton>
</DialogFooter>
</DialogContent>
</Dialog>
Expand Down Expand Up @@ -654,17 +662,18 @@ function InitPrompt({
{!hasAta && !tokenAccountsLoading && (
<p className="text-xs text-destructive">No token account found. Get some USDC first.</p>
)}
<Button
<SolanaButton
onClick={handleInitialize}
disabled={initSubscriptionAuthority.isPending || !hasAta || tokenAccountsLoading}
size="sm"
loading={initSubscriptionAuthority.isPending}
>
{initSubscriptionAuthority.isPending
? 'Initializing...'
: tokenAccountsLoading
? 'Loading...'
: 'Enable Delegations'}
</Button>
</SolanaButton>
</div>
);
}
Expand Down Expand Up @@ -748,12 +757,10 @@ function CloseSubscriptionAuthorityDialog({
</p>
<div className="space-y-1 pt-2">
<label className="text-xs text-gray-400">Type CLOSE to confirm</label>
<input
type="text"
<TextInput
value={confirmText}
onChange={e => setConfirmText(e.target.value)}
placeholder="CLOSE"
className="w-full px-3 py-2 rounded-md border border-input bg-background text-sm"
/>
</div>
</div>
Expand Down
26 changes: 10 additions & 16 deletions webapp/src/components/delegation/create-delegation-dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState, useEffect } from 'react';
import { Coins, RefreshCw, Plus, ArrowLeft } from 'lucide-react';
import { Select, SelectItem, TextInput } from '@solana/design-system';
import { Button as SolanaButton, Select, SelectItem, TextInput } from '@solana/design-system';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, DialogFooter } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
Expand Down Expand Up @@ -169,13 +169,9 @@ export function CreateDelegationDialog({ tokenMint, disabled }: CreateDelegation
return (
<Dialog open={open} onOpenChange={handleOpenChange}>
<DialogTrigger asChild>
<Button
disabled={disabled}
className="gap-2 rounded-full px-6 h-11 bg-emerald-600 hover:bg-emerald-500 text-white shadow-[0_0_20px_rgba(16,185,129,0.5)] transition-all hover:shadow-[0_0_25px_rgba(16,185,129,0.7)] border border-emerald-500/50"
>
<Plus className="h-5 w-5" />
<SolanaButton disabled={disabled} iconLeft={<Plus />} radius="round" size="lg">
Create Delegation
</Button>
</SolanaButton>
</DialogTrigger>
<DialogContent className="sm:max-w-[480px]">
<DialogHeader>
Expand Down Expand Up @@ -204,12 +200,9 @@ export function CreateDelegationDialog({ tokenMint, disabled }: CreateDelegation
/>
</div>
<DialogFooter className="mt-6">
<Button
onClick={handleContinue}
className="w-full bg-emerald-600 hover:bg-emerald-500 text-white"
>
<SolanaButton onClick={handleContinue} style={{ width: '100%' }}>
Continue
</Button>
</SolanaButton>
</DialogFooter>
</>
) : (
Expand Down Expand Up @@ -330,13 +323,14 @@ export function CreateDelegationDialog({ tokenMint, disabled }: CreateDelegation
<ArrowLeft className="h-4 w-4 mr-2" />
Back
</Button>
<Button
<SolanaButton
onClick={handleSubmit}
disabled={isPending || !isFormValid}
className="flex-1 bg-emerald-600 hover:bg-emerald-500 text-white"
loading={isPending}
style={{ flex: 1 }}
>
{isPending ? 'Creating...' : 'Create Delegation'}
</Button>
Create Delegation
</SolanaButton>
</DialogFooter>
</>
)}
Expand Down
11 changes: 6 additions & 5 deletions webapp/src/components/plan/create-plan-dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState, useMemo, useEffect } from 'react';
import { X, Plus } from 'lucide-react';
import { Select, SelectItem, TextInput } from '@solana/design-system';
import { Button as SolanaButton, Select, SelectItem, TextInput } from '@solana/design-system';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
Expand Down Expand Up @@ -453,13 +453,14 @@ export function CreatePlanDialog({ open, onOpenChange }: CreatePlanDialogProps)
</div>

<DialogFooter className="mt-4">
<Button
<SolanaButton
onClick={handleSubmit}
disabled={createPlan.isPending || !isFormValid}
className="w-full bg-emerald-600 hover:bg-emerald-500 text-white"
loading={createPlan.isPending}
style={{ width: '100%' }}
>
{createPlan.isPending ? 'Creating...' : 'Create Plan'}
</Button>
Create Plan
</SolanaButton>
</DialogFooter>
</DialogContent>
</Dialog>
Expand Down
82 changes: 41 additions & 41 deletions webapp/src/components/plan/enhanced-collect-payments.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import { useState, useMemo, useCallback } from 'react';
import { DollarSign, Users, ClipboardPen, Loader2, Clock, Star, Banknote, RefreshCw } from 'lucide-react';
import { Badge, Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@solana/design-system';
import { DollarSign, Users, ClipboardPen, Clock, Star, Banknote, RefreshCw } from 'lucide-react';
import {
Badge,
Button as SolanaButton,
SegmentedControl,
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@solana/design-system';
import { toast } from 'sonner';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
Expand Down Expand Up @@ -198,20 +208,15 @@ function CollectAllButton({
}, [eligiblePlans, rpcUrl, progAddr, collectAllPlanPayments, onComplete]);

return (
<Button
className="bg-emerald-600 hover:bg-emerald-500 text-white"
<SolanaButton
disabled={eligiblePlans.length === 0 || collecting}
loading={collecting}
onClick={handleCollectAll}
>
{collecting ? (
<>
<Loader2 className="h-4 w-4 animate-spin" />
{progress}
</>
) : (
`Collect All Pending ($${totalPendingUsd.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })})`
)}
</Button>
{collecting
? progress || 'Collecting...'
: `Collect All Pending ($${totalPendingUsd.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })})`}
</SolanaButton>
);
}

Expand Down Expand Up @@ -317,43 +322,32 @@ function EnhancedPlanCard({ planData, blockTs }: { planData: PlanSubscriberData;
{pendingUsd > 0 && (
<span className="text-emerald-400 font-medium text-sm">${pendingUsd.toFixed(2)} pending</span>
)}
<Button
className="bg-emerald-600 hover:bg-emerald-500 text-white"
<SolanaButton
size="sm"
disabled={isCollecting || eligible.length === 0}
loading={isCollecting}
onClick={e => {
e.stopPropagation();
handleCollect();
}}
>
{isCollecting ? (
<Loader2 className="h-4 w-4 animate-spin" />
) : (
`Collect $${pendingUsd.toFixed(2)}`
)}
</Button>
Collect ${pendingUsd.toFixed(2)}
</SolanaButton>
</div>
</button>

{expanded && (
<div className="border-t border-emerald-500/10">
<div className="flex gap-1 p-2 border-b border-emerald-500/10">
<Button
variant={view === 'subscribers' ? 'default' : 'ghost'}
size="sm"
className={view === 'subscribers' ? 'bg-emerald-600 hover:bg-emerald-500' : ''}
onClick={() => setView('subscribers')}
>
Subscribers
</Button>
<Button
variant={view === 'history' ? 'default' : 'ghost'}
size="sm"
className={view === 'history' ? 'bg-emerald-600 hover:bg-emerald-500' : ''}
onClick={() => setView('history')}
>
History
</Button>
<div className="p-2 border-b border-emerald-500/10">
<SegmentedControl
aria-label="Collection detail view"
value={view}
onValueChange={value => setView(value as typeof view)}
items={[
{ value: 'subscribers', label: 'Subscribers' },
{ value: 'history', label: 'History' },
]}
/>
</div>

<div className="p-3">
Expand Down Expand Up @@ -563,9 +557,15 @@ export function EnhancedCollectPayments() {
/>

<div className="flex items-center justify-end gap-2">
<Button variant="ghost" size="sm" onClick={handleRefresh} disabled={spinning}>
<RefreshCw className={`h-4 w-4 ${spinning ? 'animate-spin' : ''}`} />
</Button>
<SolanaButton
variant="secondary"
size="sm"
iconOnly
iconLeft={<RefreshCw className={spinning ? 'animate-spin' : ''} />}
aria-label="Refresh collections"
onClick={handleRefresh}
disabled={spinning}
/>
<CollectAllButton
plansData={data?.plans ?? []}
totalPendingUsd={totalPendingUsd}
Expand Down
35 changes: 17 additions & 18 deletions webapp/src/components/plan/plan-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
Plus,
X,
} from 'lucide-react';
import { Badge, Select, SelectItem, TextInput } from '@solana/design-system';
import { Badge, Button as SolanaButton, Select, SelectItem, TextInput } from '@solana/design-system';
import { Card, CardContent } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
Expand Down Expand Up @@ -362,13 +362,13 @@ function EditPlanDialog({
<Button variant="outline" onClick={() => onOpenChange(false)}>
Cancel
</Button>
<Button
<SolanaButton
onClick={handleUpdate}
disabled={updatePlan.isPending || isSunset || !isFormValid}
className="bg-emerald-600 hover:bg-emerald-500 text-white"
loading={updatePlan.isPending}
>
{updatePlan.isPending ? 'Updating...' : 'Update Plan'}
</Button>
Update Plan
</SolanaButton>
</DialogFooter>
</DialogContent>
</Dialog>
Expand Down Expand Up @@ -496,22 +496,21 @@ function SubscribeDialog({
<div className="text-sm text-amber-400 p-3 rounded-lg border border-amber-500/30 bg-amber-500/5">
Your SubscriptionAuthority account must be initialized for this token before subscribing.
</div>
<Button
<SolanaButton
onClick={handleInit}
disabled={initSubscriptionAuthority.isPending}
className="w-full bg-amber-600 hover:bg-amber-500 text-white"
loading={initSubscriptionAuthority.isPending}
style={{ width: '100%' }}
>
{initSubscriptionAuthority.isPending
? 'Initializing...'
: 'Initialize SubscriptionAuthority'}
</Button>
Initialize SubscriptionAuthority
</SolanaButton>
</div>
) : (
<DialogFooter>
<Button variant="outline" onClick={() => onOpenChange(false)}>
Cancel
</Button>
<Button
<SolanaButton
onClick={() =>
subscribe.mutate(
{
Expand All @@ -526,10 +525,10 @@ function SubscribeDialog({
)
}
disabled={subscribe.isPending}
className="bg-emerald-600 hover:bg-emerald-500 text-white"
loading={subscribe.isPending}
>
{subscribe.isPending ? 'Subscribing...' : 'Subscribe'}
</Button>
Subscribe
</SolanaButton>
</DialogFooter>
)}
</DialogContent>
Expand Down Expand Up @@ -854,17 +853,17 @@ export function PlanCard({
Already Subscribed
</Badge>
) : (
<Button
<SolanaButton
size="sm"
onClick={(e: React.MouseEvent) => {
e.stopPropagation();
setSubscribeOpen(true);
}}
disabled={isSunset || planExpired}
className="w-full h-9 bg-emerald-600 hover:bg-emerald-500 text-white"
style={{ width: '100%' }}
>
Subscribe
</Button>
</SolanaButton>
)}
</div>
)}
Expand Down
Loading
Loading