Skip to content

Commit 7bd645c

Browse files
committed
Update page.tsx
1 parent 16117da commit 7bd645c

1 file changed

Lines changed: 65 additions & 53 deletions

File tree

src/app/programs/page.tsx

Lines changed: 65 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
DialogContent, DialogActions, Alert, CircularProgress,
88
Select, MenuItem, FormControl, InputLabel, IconButton, Tooltip,
99
Accordion, AccordionSummary, AccordionDetails, useMediaQuery, useTheme,
10+
Tabs, Tab,
1011
} from "@mui/material";
1112
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
1213
import EditIcon from "@mui/icons-material/Edit";
@@ -304,6 +305,8 @@ function ProgramDetail({ programId }: { programId: number }) {
304305
const [parentDisclaimer, setParentDisclaimer] = useState(false);
305306
const [withAmount, setWithAmount] = useState("");
306307
const [withDisclaimer, setWithDisclaimer] = useState(false);
308+
const [tokenTab, setTokenTab] = useState(0);
309+
const canTransferSub = isAdmin || isPA || role === MemberRoleEnum.TeamLeader;
307310
const isMember = role > 0 || isAdmin;
308311

309312
const paWalletValid = !paWallet || isValidAddress(paWallet);
@@ -487,23 +490,31 @@ function ProgramDetail({ programId }: { programId: number }) {
487490
{/* Token Actions */}
488491
{isMember && program.active && (
489492
<Paper sx={{ p: 2, mb: 3 }}>
490-
<Typography variant="h6" gutterBottom>Token Actions</Typography>
491-
{walletBalance != null && (
492-
<Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
493-
Wallet Balance: {formatFula(walletBalance)} FULA
494-
</Typography>
495-
)}
496-
<Grid container spacing={3}>
497-
{/* Deposit */}
498-
<Grid item xs={12} sm={6} md={3}>
499-
<Typography variant="subtitle2" gutterBottom>Deposit</Typography>
493+
<Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "center", mb: 1 }}>
494+
<Typography variant="h6">Token Actions</Typography>
495+
{walletBalance != null && (
496+
<Typography variant="body2" color="text.secondary">
497+
Wallet: {formatFula(walletBalance)} FULA
498+
</Typography>
499+
)}
500+
</Box>
501+
<Tabs value={tokenTab} onChange={(_, v) => setTokenTab(v)} variant="scrollable" scrollButtons="auto">
502+
<Tab label="Deposit" />
503+
{canTransferSub && <Tab label="Transfer to Sub-Member" />}
504+
<Tab label="Transfer to Parent" />
505+
<Tab label="Withdraw" />
506+
</Tabs>
507+
508+
{/* Deposit */}
509+
{tokenTab === 0 && (
510+
<Box sx={{ pt: 2, maxWidth: 480 }}>
500511
<TextField label="Amount (FULA)" value={depAmount} onChange={(e) => setDepAmount(e.target.value)}
501512
fullWidth size="small" type="number" />
502513
<TextField label="Note (max 128)" value={depNote}
503514
onChange={(e) => setDepNote(e.target.value.slice(0, 128))}
504515
fullWidth size="small" sx={{ mt: 1 }} inputProps={{ maxLength: 128 }} />
505516
<OnChainDisclaimer accepted={depDisclaimer} onChange={setDepDisclaimer} />
506-
<Button size="small" variant="contained" fullWidth sx={{ mt: 1 }}
517+
<Button variant="contained" fullWidth sx={{ mt: 1 }}
507518
onClick={() => depositTokens(programId, depAmount, 0, depNote)}
508519
disabled={isDepPending || !depAmount || !depDisclaimer}>
509520
{isDepApproving ? <><CircularProgress size={16} sx={{ mr: 0.5 }} /> Approving...</>
@@ -512,43 +523,43 @@ function ProgramDetail({ programId }: { programId: number }) {
512523
</Button>
513524
{depSuccess && <Alert severity="success" sx={{ mt: 1 }}>Deposited!</Alert>}
514525
{depError && <Alert severity="error" sx={{ mt: 1 }}>{formatContractError(depError)}</Alert>}
515-
</Grid>
526+
</Box>
527+
)}
516528

517-
{/* Transfer to Sub-Member */}
518-
{(isAdmin || isPA || role === MemberRoleEnum.TeamLeader) && (
519-
<Grid item xs={12} sm={6} md={3}>
520-
<Typography variant="subtitle2" gutterBottom>Transfer to Sub-Member</Typography>
521-
<TextField label="Recipient Wallet" value={transTo} onChange={(e) => setTransTo(e.target.value)}
522-
fullWidth size="small" error={!!transTo && !isValidAddress(transTo)} />
523-
<TextField label="Amount (FULA)" value={transAmount} onChange={(e) => setTransAmount(e.target.value)}
529+
{/* Transfer to Sub-Member */}
530+
{canTransferSub && tokenTab === 1 && (
531+
<Box sx={{ pt: 2, maxWidth: 480 }}>
532+
<TextField label="Recipient Wallet" value={transTo} onChange={(e) => setTransTo(e.target.value)}
533+
fullWidth size="small" error={!!transTo && !isValidAddress(transTo)} />
534+
<TextField label="Amount (FULA)" value={transAmount} onChange={(e) => setTransAmount(e.target.value)}
535+
fullWidth size="small" type="number" sx={{ mt: 1 }} />
536+
<FormControl fullWidth size="small" sx={{ mt: 1 }}>
537+
<InputLabel>Lock</InputLabel>
538+
<Select value={transLocked ? "locked" : "unlocked"}
539+
onChange={(e) => setTransLocked(e.target.value === "locked")} label="Lock">
540+
<MenuItem value="locked">Permanently Locked</MenuItem>
541+
<MenuItem value="unlocked">Unlocked / Time-locked</MenuItem>
542+
</Select>
543+
</FormControl>
544+
{!transLocked && (
545+
<TextField label="Lock Days (0 = unlocked)" value={transLockDays}
546+
onChange={(e) => setTransLockDays(e.target.value)}
524547
fullWidth size="small" type="number" sx={{ mt: 1 }} />
525-
<FormControl fullWidth size="small" sx={{ mt: 1 }}>
526-
<InputLabel>Lock</InputLabel>
527-
<Select value={transLocked ? "locked" : "unlocked"}
528-
onChange={(e) => setTransLocked(e.target.value === "locked")} label="Lock">
529-
<MenuItem value="locked">Permanently Locked</MenuItem>
530-
<MenuItem value="unlocked">Unlocked / Time-locked</MenuItem>
531-
</Select>
532-
</FormControl>
533-
{!transLocked && (
534-
<TextField label="Lock Days (0 = unlocked)" value={transLockDays}
535-
onChange={(e) => setTransLockDays(e.target.value)}
536-
fullWidth size="small" type="number" sx={{ mt: 1 }} />
537-
)}
538-
<OnChainDisclaimer accepted={transDisclaimer} onChange={setTransDisclaimer} />
539-
<Button size="small" variant="contained" fullWidth sx={{ mt: 1 }}
540-
onClick={() => transfer(programId, transTo as `0x${string}`, transAmount, transLocked, parseInt(transLockDays) || 0)}
541-
disabled={isTransPending || isTransConf || !transTo || !transAmount || !isValidAddress(transTo) || !transDisclaimer}>
542-
{isTransPending || isTransConf ? <CircularProgress size={16} /> : "Transfer"}
543-
</Button>
544-
{transSuccess && <Alert severity="success" sx={{ mt: 1 }}>Transferred!</Alert>}
545-
{transError && <Alert severity="error" sx={{ mt: 1 }}>{formatContractError(transError)}</Alert>}
546-
</Grid>
547-
)}
548+
)}
549+
<OnChainDisclaimer accepted={transDisclaimer} onChange={setTransDisclaimer} />
550+
<Button variant="contained" fullWidth sx={{ mt: 1 }}
551+
onClick={() => transfer(programId, transTo as `0x${string}`, transAmount, transLocked, parseInt(transLockDays) || 0)}
552+
disabled={isTransPending || isTransConf || !transTo || !transAmount || !isValidAddress(transTo) || !transDisclaimer}>
553+
{isTransPending || isTransConf ? <CircularProgress size={16} /> : "Transfer"}
554+
</Button>
555+
{transSuccess && <Alert severity="success" sx={{ mt: 1 }}>Transferred!</Alert>}
556+
{transError && <Alert severity="error" sx={{ mt: 1 }}>{formatContractError(transError)}</Alert>}
557+
</Box>
558+
)}
548559

549-
{/* Transfer to Parent */}
550-
<Grid item xs={12} sm={6} md={3}>
551-
<Typography variant="subtitle2" gutterBottom>Transfer to Parent</Typography>
560+
{/* Transfer to Parent */}
561+
{tokenTab === (canTransferSub ? 2 : 1) && (
562+
<Box sx={{ pt: 2, maxWidth: 480 }}>
552563
{transferLimit != null && Number(transferLimit) > 0 && (
553564
<Alert severity="info" sx={{ mb: 1 }}>Limit: {String(transferLimit)}% of total balance</Alert>
554565
)}
@@ -558,30 +569,31 @@ function ProgramDetail({ programId }: { programId: number }) {
558569
<TextField label="Amount (FULA)" value={parentAmount} onChange={(e) => setParentAmount(e.target.value)}
559570
fullWidth size="small" type="number" sx={{ mt: 1 }} />
560571
<OnChainDisclaimer accepted={parentDisclaimer} onChange={setParentDisclaimer} />
561-
<Button size="small" variant="contained" fullWidth sx={{ mt: 1 }}
572+
<Button variant="contained" fullWidth sx={{ mt: 1 }}
562573
onClick={() => transferBack(programId, (parentTo || "0x0000000000000000000000000000000000000000") as `0x${string}`, parentAmount)}
563574
disabled={isTransBackPending || isTransBackConf || !parentAmount || !parentDisclaimer}>
564575
{isTransBackPending || isTransBackConf ? <CircularProgress size={16} /> : "Transfer to Parent"}
565576
</Button>
566577
{transBackSuccess && <Alert severity="success" sx={{ mt: 1 }}>Transferred!</Alert>}
567578
{transBackError && <Alert severity="error" sx={{ mt: 1 }}>{formatContractError(transBackError)}</Alert>}
568-
</Grid>
579+
</Box>
580+
)}
569581

570-
{/* Withdraw */}
571-
<Grid item xs={12} sm={6} md={3}>
572-
<Typography variant="subtitle2" gutterBottom>Withdraw</Typography>
582+
{/* Withdraw */}
583+
{tokenTab === (canTransferSub ? 3 : 2) && (
584+
<Box sx={{ pt: 2, maxWidth: 480 }}>
573585
<TextField label="Amount (FULA)" value={withAmount} onChange={(e) => setWithAmount(e.target.value)}
574586
fullWidth size="small" type="number" />
575587
<OnChainDisclaimer accepted={withDisclaimer} onChange={setWithDisclaimer} />
576-
<Button size="small" variant="contained" fullWidth sx={{ mt: 1 }}
588+
<Button variant="contained" fullWidth sx={{ mt: 1 }}
577589
onClick={() => withdraw(programId, withAmount)}
578590
disabled={isWithPending || isWithConf || !withAmount || !withDisclaimer}>
579591
{isWithPending || isWithConf ? <CircularProgress size={16} /> : "Withdraw"}
580592
</Button>
581593
{withSuccess && <Alert severity="success" sx={{ mt: 1 }}>Withdrawn!</Alert>}
582594
{withError && <Alert severity="error" sx={{ mt: 1 }}>{formatContractError(withError)}</Alert>}
583-
</Grid>
584-
</Grid>
595+
</Box>
596+
)}
585597
</Paper>
586598
)}
587599

0 commit comments

Comments
 (0)