This commit is contained in:
root
2025-12-22 06:43:19 +01:00
parent a940d51475
commit 6f4ca75faf
25 changed files with 1350 additions and 221 deletions

View File

@@ -8,11 +8,15 @@ interface Buyer {
username: string
email: string
created_at?: string
referral_count?: number
hasWholesaleAccess?: boolean
hasInnerCircleAccess?: boolean
}
export default function BuyersManagementPage() {
const router = useRouter()
const [buyers, setBuyers] = useState<Buyer[]>([])
const [filteredBuyers, setFilteredBuyers] = useState<Buyer[]>([])
const [loading, setLoading] = useState(true)
const [authenticated, setAuthenticated] = useState(false)
const [editingBuyer, setEditingBuyer] = useState<Buyer | null>(null)
@@ -21,6 +25,10 @@ export default function BuyersManagementPage() {
email: '',
password: '',
})
const [filters, setFilters] = useState({
wholesaleOnly: false,
innerCircleOnly: false,
})
useEffect(() => {
// Check authentication
@@ -44,7 +52,9 @@ export default function BuyersManagementPage() {
const response = await fetch('/api/buyers')
if (response.ok) {
const data = await response.json()
setBuyers(Array.isArray(data) ? data : [])
const buyersList = Array.isArray(data) ? data : []
setBuyers(buyersList)
applyFilters(buyersList, filters)
}
} catch (error) {
console.error('Error fetching buyers:', error)
@@ -53,6 +63,24 @@ export default function BuyersManagementPage() {
}
}
const applyFilters = (buyersList: Buyer[], currentFilters: typeof filters) => {
let filtered = [...buyersList]
if (currentFilters.wholesaleOnly) {
filtered = filtered.filter(buyer => buyer.hasWholesaleAccess)
}
if (currentFilters.innerCircleOnly) {
filtered = filtered.filter(buyer => buyer.hasInnerCircleAccess)
}
setFilteredBuyers(filtered)
}
useEffect(() => {
applyFilters(buyers, filters)
}, [filters])
const handleEdit = (buyer: Buyer) => {
setEditingBuyer(buyer)
setFormData({
@@ -173,11 +201,62 @@ export default function BuyersManagementPage() {
</button>
</div>
{buyers.length === 0 ? (
<div style={{
marginBottom: '20px',
padding: '16px',
background: 'var(--card)',
borderRadius: '8px',
border: '1px solid var(--border)'
}}>
<h3 style={{ marginBottom: '12px', fontSize: '16px' }}>Filters</h3>
<div style={{ display: 'flex', gap: '20px', flexWrap: 'wrap' }}>
<label style={{
display: 'flex',
alignItems: 'center',
gap: '8px',
cursor: 'pointer',
userSelect: 'none'
}}>
<input
type="checkbox"
checked={filters.wholesaleOnly}
onChange={(e) => setFilters({ ...filters, wholesaleOnly: e.target.checked })}
style={{ width: '16px', height: '16px', cursor: 'pointer' }}
/>
<span>Wholesale Access (3+ referrals)</span>
</label>
<label style={{
display: 'flex',
alignItems: 'center',
gap: '8px',
cursor: 'pointer',
userSelect: 'none'
}}>
<input
type="checkbox"
checked={filters.innerCircleOnly}
onChange={(e) => setFilters({ ...filters, innerCircleOnly: e.target.checked })}
style={{ width: '16px', height: '16px', cursor: 'pointer' }}
/>
<span>Inner Circle Access (10+ referrals)</span>
</label>
</div>
{(filters.wholesaleOnly || filters.innerCircleOnly) && (
<p style={{
marginTop: '12px',
color: 'var(--muted)',
fontSize: '14px'
}}>
Showing {filteredBuyers.length} of {buyers.length} buyers
</p>
)}
</div>
{(filters.wholesaleOnly || filters.innerCircleOnly ? filteredBuyers : buyers).length === 0 ? (
<p style={{ color: 'var(--muted)' }}>No buyers found</p>
) : (
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
{buyers.map((buyer) => (
{(filters.wholesaleOnly || filters.innerCircleOnly ? filteredBuyers : buyers).map((buyer) => (
<div
key={buyer.id}
className="drop-card"
@@ -273,10 +352,35 @@ export default function BuyersManagementPage() {
ID: {buyer.id}
</p>
{buyer.created_at && (
<p style={{ color: 'var(--muted)', fontSize: '12px' }}>
<p style={{ color: 'var(--muted)', fontSize: '12px', marginBottom: '4px' }}>
Created: {new Date(buyer.created_at).toLocaleString()}
</p>
)}
<div style={{
display: 'flex',
gap: '8px',
marginTop: '8px',
flexWrap: 'wrap'
}}>
<span style={{
padding: '4px 8px',
borderRadius: '4px',
fontSize: '12px',
background: buyer.hasWholesaleAccess ? '#10b981' : '#6b7280',
color: '#fff'
}}>
{buyer.referral_count || 0} referrals - Wholesale {buyer.hasWholesaleAccess ? '✓' : '✗'}
</span>
<span style={{
padding: '4px 8px',
borderRadius: '4px',
fontSize: '12px',
background: buyer.hasInnerCircleAccess ? '#8b5cf6' : '#6b7280',
color: '#fff'
}}>
Inner Circle {buyer.hasInnerCircleAccess ? '✓' : '✗'}
</span>
</div>
</div>
<div style={{ display: 'flex', gap: '8px' }}>
<button

View File

@@ -537,7 +537,7 @@ export default function DropsManagementPage() {
onChange={(e) => setFormData({ ...formData, ppu: e.target.value })}
required
min="1"
placeholder="2500 = 2.50 CHF"
placeholder="2500 = 2.50 EUR"
style={{
width: '100%',
padding: '8px',
@@ -959,7 +959,7 @@ export default function DropsManagementPage() {
<div style={{ flex: 1 }}>
<h3 style={{ marginBottom: '8px' }}>{drop.item}</h3>
<p style={{ color: 'var(--muted)', fontSize: '14px', marginBottom: '4px' }}>
ID: {drop.id} · Size: {drop.size}{drop.unit} · Price: {(drop.ppu / 1000).toFixed(2)} CHF / {drop.unit}
ID: {drop.id} · Size: {drop.size}{drop.unit} · Price: {(drop.ppu / 1000).toFixed(2)} EUR / {drop.unit}
</p>
<p style={{ color: 'var(--muted)', fontSize: '12px', marginBottom: '12px' }}>
Created: {new Date(drop.created_at).toLocaleString()}