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
30 changes: 9 additions & 21 deletions src/components/features/dashboard/KpiCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,20 @@ export const KpiCard = ({
? formatPercentage(value)
: String(value ?? '');

const resolvedTone = highlighted ? 'highlight' : tone;
const cardVariant = highlighted ? 'highlight' : 'default';

const cardClassName =
resolvedTone === 'highlight'
? 'bg-gradient-to-r from-primary to-[#4a9d8e] text-white'
: resolvedTone === 'neutral'
? 'bg-[rgba(101,167,165,0.06)] border border-border-accent'
: 'bg-dark-card';
const titleClassName = highlighted ? 'text-sm text-[#8dc8bf]' : 'text-sm text-text-muted';

const titleClassName =
resolvedTone === 'highlight'
? 'text-sm text-white/90'
: resolvedTone === 'neutral'
? 'text-sm text-text-muted'
: 'text-sm text-text-muted';

const valueClassName =
resolvedTone === 'highlight'
? 'text-3xl font-bold text-white'
: resolvedTone === 'neutral'
? 'text-2xl font-semibold text-text-primary'
: 'text-2xl font-semibold text-text-primary';
const valueClassName = highlighted
? 'text-3xl font-bold text-text-primary'
: tone === 'neutral'
? 'text-2xl font-semibold text-text-primary'
: 'text-2xl font-semibold text-text-primary';

return (
<Card
className={`${cardClassName} transition-transform duration-200 ease-out hover:-translate-y-0.5`}
variant={cardVariant}
className="transition-transform duration-200 ease-out hover:-translate-y-0.5"
>
<div className="space-y-2">
<p className={titleClassName}>{title}</p>
Expand Down
13 changes: 6 additions & 7 deletions src/components/features/deposits/DepositOptionCard.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useState } from 'react';
import { Card } from '../../ui/Card';
import { Button } from '../../ui/Button';
import { useTranslation } from 'react-i18next';

const COPYABLE_KEYS = [
Expand Down Expand Up @@ -31,11 +30,11 @@ export const DepositOptionCard = ({ option }) => {
const detailEntries = Object.entries(details).filter(([, v]) => v);

return (
<Card className="transition-colors hover:border-border-accent">
<Card variant="compact" className="transition-colors hover:border-[rgba(101,167,165,0.35)]">
<div className="space-y-3">
<div className="flex items-center justify-between">
<h4 className="font-semibold text-text-primary">{option.label}</h4>
<span className="text-xs font-medium text-text-muted bg-dark-section rounded-full px-2 py-0.5">
<span className="text-xs font-medium text-text-muted bg-[rgba(20,20,20,0.55)] rounded-full px-2 py-0.5">
{option.currency}
</span>
</div>
Expand All @@ -48,13 +47,13 @@ export const DepositOptionCard = ({ option }) => {
<p className="text-sm text-text-primary font-mono break-all">{value}</p>
</div>
{COPYABLE_KEYS.includes(key) && (
<Button
<button
type="button"
onClick={() => handleCopy(value, key)}
variant="outline"
className="shrink-0 text-xs py-1 px-3"
className="btn-copy shrink-0 text-xs py-1.5 px-3"
>
{copiedKey === key ? t('deposits.copied') : t('deposits.copy')}
</Button>
</button>
)}
</div>
))}
Expand Down
10 changes: 5 additions & 5 deletions src/components/features/requests/DepositForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ export const DepositForm = ({ userEmail, depositOptions = [] }) => {
ref={fileInputRef}
accept="image/jpeg,image/png,image/webp,application/pdf"
onChange={handleFileChange}
className="block w-full text-sm text-text-muted file:mr-4 file:py-2 file:px-4 file:rounded-lg file:border-0 file:text-sm file:font-semibold file:bg-primary/10 file:text-primary hover:file:bg-primary/20 cursor-pointer"
className="block w-full text-sm text-text-muted file:mr-4 file:py-2 file:px-4 file:rounded-lg file:border-0 file:text-sm file:font-semibold file:bg-[rgba(101,167,165,0.10)] file:text-[#8dc8bf] hover:file:bg-[rgba(101,167,165,0.18)] cursor-pointer"
/>
{attachment && (
<p className="mt-1 text-xs text-success">
Expand All @@ -221,7 +221,7 @@ export const DepositForm = ({ userEmail, depositOptions = [] }) => {
)}
</div>

<div className="bg-accent/30 p-4 rounded-lg text-sm text-text-primary">
<div className="info-box text-sm text-text-primary">
<p className="font-medium mb-1">{t('deposits.processingHoursTitle')}</p>
<p>• {t('deposits.processingHoursLine1')}</p>
<p>• {t('deposits.processingHoursLine2')}</p>
Expand All @@ -232,10 +232,10 @@ export const DepositForm = ({ userEmail, depositOptions = [] }) => {
role="alert"
className={`rounded-lg p-4 ${
message.type === 'error'
? 'bg-[rgba(239,83,80,0.15)] text-error'
? 'badge-rejected'
: message.type === 'success'
? 'bg-[rgba(76,175,80,0.15)] text-success'
: 'bg-[rgba(101,167,165,0.15)] text-info'
? 'badge-completed'
: 'info-box'
}`}
>
<p className="text-sm">{message.text}</p>
Expand Down
10 changes: 4 additions & 6 deletions src/components/features/requests/WithdrawalForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export const WithdrawalForm = ({ userEmail, currentBalance }) => {
<span className="font-semibold">{formatCurrency(confirmModal.withdrawalAmount)}</span>
</div>
{confirmModal.hasFee ? (
<div className="flex justify-between text-blue-700">
<div className="flex justify-between text-primary">
<span>Comisión de trading ({confirmModal.feePercentage}%)</span>
<span className="font-semibold">{formatCurrency(confirmModal.feeAmount)}</span>
</div>
Expand All @@ -115,7 +115,7 @@ export const WithdrawalForm = ({ userEmail, currentBalance }) => {
</p>
)}
{confirmModal.hasFee && (
<div className="border-t border-border-dark pt-3 flex justify-between font-semibold text-text-primary">
<div className="border-t border-[rgba(255,255,255,0.08)] pt-3 flex justify-between font-semibold text-text-primary">
<span>Total debitado del portfolio</span>
<span>
{formatCurrency(confirmModal.withdrawalAmount + confirmModal.feeAmount)}
Expand Down Expand Up @@ -193,7 +193,7 @@ export const WithdrawalForm = ({ userEmail, currentBalance }) => {
/>
)}

<div className="bg-accent/30 p-4 rounded-lg text-sm text-text-primary">
<div className="info-box text-sm text-text-primary">
<p className="font-medium mb-1">{t('withdrawals.processingHoursTitle')}</p>
<p>• {t('withdrawals.processingHoursLine1')}</p>
<p>• {t('withdrawals.processingHoursLine2')}</p>
Expand All @@ -204,9 +204,7 @@ export const WithdrawalForm = ({ userEmail, currentBalance }) => {
<div
role="alert"
className={`p-4 rounded-lg ${
message.type === 'success'
? 'bg-[rgba(76,175,80,0.15)] text-success'
: 'bg-[rgba(239,83,80,0.15)] text-error'
message.type === 'success' ? 'badge-completed' : 'badge-rejected'
}`}
>
{message.text}
Expand Down
11 changes: 7 additions & 4 deletions src/components/ui/Button.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ export const Button = ({
'px-6 py-3 rounded-lg font-medium transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-dark-bg disabled:opacity-50 disabled:cursor-not-allowed';

const variants = {
primary: 'bg-primary text-white hover:bg-primary/80 focus:ring-primary',
primary:
'bg-[rgba(101,167,165,0.15)] text-[#8dc8bf] border border-[rgba(101,167,165,0.35)] hover:bg-[rgba(101,167,165,0.25)] hover:border-[rgba(101,167,165,0.55)] focus:ring-primary',
secondary:
'bg-accent-dim text-white border border-[rgba(101,167,165,0.45)] hover:bg-accent-glow hover:border-primary focus:ring-primary',
danger: 'bg-error text-white hover:bg-error/80 focus:ring-error',
'bg-[rgba(101,167,165,0.10)] text-[#8dc8bf] border border-[rgba(101,167,165,0.35)] hover:bg-[rgba(101,167,165,0.18)] hover:border-[rgba(101,167,165,0.55)] focus:ring-primary',
danger:
'bg-[rgba(196,107,107,0.14)] text-[#c46b6b] border border-[rgba(196,107,107,0.18)] hover:bg-[rgba(196,107,107,0.22)] focus:ring-error',
outline:
'border border-[rgba(101,167,165,0.45)] text-primary bg-accent-dim hover:bg-accent-glow hover:border-primary focus:ring-primary',
'bg-[rgba(101,167,165,0.10)] text-[#8dc8bf] border border-[rgba(101,167,165,0.35)] hover:bg-[rgba(101,167,165,0.18)] hover:border-[rgba(101,167,165,0.55)] focus:ring-primary',
copy: 'btn-copy text-xs focus:ring-primary',
};

return (
Expand Down
8 changes: 4 additions & 4 deletions src/components/ui/Button.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,25 @@ describe('Button', () => {
it('applies primary variant styles by default', () => {
render(<Button>Primary</Button>);
const button = screen.getByText('Primary');
expect(button).toHaveClass('bg-primary');
expect(button).toHaveClass('focus:ring-primary');
});

it('applies secondary variant styles', () => {
render(<Button variant="secondary">Secondary</Button>);
const button = screen.getByText('Secondary');
expect(button).toHaveClass('bg-accent-dim');
expect(button).toHaveClass('focus:ring-primary');
});

it('applies danger variant styles', () => {
render(<Button variant="danger">Danger</Button>);
const button = screen.getByText('Danger');
expect(button).toHaveClass('bg-error');
expect(button).toHaveClass('focus:ring-error');
});

it('applies outline variant styles', () => {
render(<Button variant="outline">Outline</Button>);
const button = screen.getByText('Outline');
expect(button).toHaveClass('bg-accent-dim');
expect(button).toHaveClass('focus:ring-primary');
});

it('disables button when disabled prop is true', () => {
Expand Down
13 changes: 9 additions & 4 deletions src/components/ui/Card.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
export const Card = ({ children, className = '', title }) => {
export const Card = ({ children, className = '', title, variant = 'default' }) => {
const variantClass =
variant === 'highlight'
? 'winbit-card--highlight'
: variant === 'compact'
? 'winbit-card--compact'
: 'winbit-card';

return (
<div
className={`bg-dark-card rounded-lg border border-border-dark p-6 backdrop-blur-sm ${className}`}
>
<div className={`${variantClass} ${className}`}>
{title && <h3 className="text-xl font-semibold mb-4 text-text-primary">{title}</h3>}
{children}
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/Card.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ describe('Card', () => {
it('has default card styles', () => {
const { container } = render(<Card>Content</Card>);
const card = container.firstChild;
expect(card).toHaveClass('bg-dark-card', 'rounded-lg', 'border-border-dark');
expect(card).toHaveClass('winbit-card');
});
});
111 changes: 109 additions & 2 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

@layer base {
body {
background: #0a0a0a;
background: #0d0f10;
color: #e8e8e8;
font-family:
'Montserrat',
Expand All @@ -18,7 +18,7 @@
input,
select,
textarea {
background: rgba(20, 20, 20, 0.5);
background: rgba(15, 18, 18, 0.8);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 0.5rem;
padding: 0.75rem 1rem;
Expand Down Expand Up @@ -51,4 +51,111 @@
.container {
@apply max-w-7xl mx-auto px-4 sm:px-6 lg:px-8;
}

.winbit-card {
background: linear-gradient(180deg, rgba(18, 24, 24, 0.92) 0%, rgba(15, 18, 18, 0.96) 100%);
border: 1px solid rgba(101, 167, 165, 0.22);
border-radius: 8px;
padding: 28px 26px;
box-shadow:
inset 3px 0 0 rgba(101, 167, 165, 0.22),
0 10px 28px rgba(0, 0, 0, 0.22);
}

.winbit-card--highlight {
background: linear-gradient(180deg, rgba(28, 40, 40, 0.94) 0%, rgba(20, 28, 28, 0.98) 100%);
border: 1px solid rgba(101, 167, 165, 0.32);
border-radius: 8px;
padding: 28px 26px;
box-shadow:
inset 4px 0 0 rgba(101, 167, 165, 0.3),
0 12px 30px rgba(0, 0, 0, 0.24);
}

.winbit-card--compact {
background: linear-gradient(180deg, rgba(18, 24, 24, 0.92) 0%, rgba(15, 18, 18, 0.96) 100%);
border: 1px solid rgba(101, 167, 165, 0.22);
border-radius: 8px;
padding: 20px 22px;
box-shadow:
inset 3px 0 0 rgba(101, 167, 165, 0.22),
0 10px 28px rgba(0, 0, 0, 0.22);
}

.section-subtitle {
color: #65a7a5;
padding-bottom: 8px;
border-bottom: 1px solid rgba(101, 167, 165, 0.35);
font-size: 0.95rem;
margin-top: 4px;
}

.badge-completed {
background: rgba(101, 167, 165, 0.14);
color: #8dc8bf;
border: 1px solid rgba(101, 167, 165, 0.2);
}

.badge-pending {
background: rgba(194, 170, 114, 0.14);
color: #c2aa72;
border: 1px solid rgba(194, 170, 114, 0.18);
}

.badge-rejected {
background: rgba(196, 107, 107, 0.14);
color: #c46b6b;
border: 1px solid rgba(196, 107, 107, 0.18);
}

.badge-cancelled {
background: rgba(20, 20, 20, 0.55);
color: #888888;
border: 1px solid rgba(255, 255, 255, 0.08);
}

.info-box {
background: rgba(101, 167, 165, 0.1);
border: 1px solid rgba(101, 167, 165, 0.22);
border-radius: 8px;
padding: 20px;
}

.row-positive {
background: rgba(101, 167, 165, 0.1);
}

.row-positive:hover {
background: rgba(101, 167, 165, 0.16);
}

.row-negative {
background: rgba(196, 107, 107, 0.1);
}

.row-negative:hover {
background: rgba(196, 107, 107, 0.16);
}

.row-fee {
background: rgba(101, 167, 165, 0.1);
}

.row-fee:hover {
background: rgba(101, 167, 165, 0.16);
}

.btn-copy {
background: rgba(101, 167, 165, 0.1);
border: 1px solid rgba(101, 167, 165, 0.35);
color: #8dc8bf;
border-radius: 6px;
padding: 8px 16px;
transition: all 0.2s ease;
}

.btn-copy:hover {
background: rgba(101, 167, 165, 0.18);
border-color: rgba(101, 167, 165, 0.55);
}
}
Loading
Loading