Skip to content

Commit c1eba63

Browse files
committed
PA also able to edit program
1 parent 7bd645c commit c1eba63

File tree

4 files changed

+32
-19
lines changed

4 files changed

+32
-19
lines changed

.claude/settings.local.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@
3737
"Bash(find /mnt/e/GitHub/fula-chain -name *.ts -o -name *.js)",
3838
"Bash(find /mnt/e/GitHub/fula-chain -type f \\\\\\(-name *.test.ts -o -name *.spec.ts -o -name *test*.ts \\\\\\))",
3939
"Bash(npm ls:*)",
40-
"Bash(npm view:*)"
40+
"Bash(npm view:*)",
41+
"Bash(ls /mnt/e/GitHub/rewards-program/src/app/global-error*)",
42+
"Bash(ls /mnt/e/GitHub/rewards-program/src/app/error*)"
4143
]
4244
}
4345
}

src/app/balance/page.tsx

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
Typography, Box, Paper, Grid, Chip, Table, TableBody, TableCell,
66
TableContainer, TableHead, TableRow, TextField, Button, Alert,
77
CircularProgress, Select, MenuItem, FormControl, InputLabel,
8-
useMediaQuery, useTheme,
8+
useMediaQuery, useTheme, Tabs, Tab,
99
} from "@mui/material";
1010
import { useAccount, useReadContract, useReadContracts } from "wagmi";
1111
import { useSearchParams } from "next/navigation";
@@ -157,6 +157,7 @@ function OwnerActions({ memberWallet }: { memberWallet: string }) {
157157
const { data: rewardTypesData } = useRewardTypes();
158158

159159
const [disclaimer, setDisclaimer] = useState(false);
160+
const [actionTab, setActionTab] = useState(0);
160161

161162
if (!isOwner) return null;
162163

@@ -166,10 +167,15 @@ function OwnerActions({ memberWallet }: { memberWallet: string }) {
166167
<TextField label="Program ID" value={actionProgramId} onChange={(e) => setActionProgramId(e.target.value)}
167168
type="number" size="small" sx={{ width: 150, mb: 2 }} />
168169

169-
<Grid container spacing={3}>
170-
{/* Deposit */}
171-
<Grid item xs={12} md={4}>
172-
<Typography variant="subtitle2" gutterBottom>Deposit FULA</Typography>
170+
<Tabs value={actionTab} onChange={(_, v) => setActionTab(v)} sx={{ borderBottom: 1, borderColor: "divider" }}>
171+
<Tab label="Deposit" />
172+
<Tab label="Transfer to Parent" />
173+
<Tab label="Withdraw" />
174+
</Tabs>
175+
176+
{/* Deposit */}
177+
{actionTab === 0 && (
178+
<Box sx={{ pt: 2, maxWidth: 480 }}>
173179
<TextField label="Amount (FULA)" value={depositAmount} onChange={(e) => setDepositAmount(e.target.value)}
174180
fullWidth size="small" type="number" />
175181
<FormControl fullWidth size="small" sx={{ mt: 1 }}>
@@ -196,11 +202,12 @@ function OwnerActions({ memberWallet }: { memberWallet: string }) {
196202
</Box>
197203
{depositSuccess && <Alert severity="success" sx={{ mt: 1 }}>Deposited!</Alert>}
198204
{depositError && <Alert severity="error" sx={{ mt: 1 }}>{formatContractError(depositError)}</Alert>}
199-
</Grid>
205+
</Box>
206+
)}
200207

201-
{/* Transfer to Parent */}
202-
<Grid item xs={12} md={4}>
203-
<Typography variant="subtitle2" gutterBottom>Transfer to Parent</Typography>
208+
{/* Transfer to Parent */}
209+
{actionTab === 1 && (
210+
<Box sx={{ pt: 2, maxWidth: 480 }}>
204211
{transferLimitData != null && Number(transferLimitData) > 0 && (
205212
<Alert severity="info" sx={{ mb: 1 }}>
206213
Transfer limit: <strong>{Number(transferLimitData)}%</strong> of total balance (Clients only).
@@ -217,11 +224,12 @@ function OwnerActions({ memberWallet }: { memberWallet: string }) {
217224
</Button>
218225
{transBackSuccess && <Alert severity="success" sx={{ mt: 1 }}>Transferred!</Alert>}
219226
{transBackError && <Alert severity="error" sx={{ mt: 1 }}>{formatContractError(transBackError)}</Alert>}
220-
</Grid>
227+
</Box>
228+
)}
221229

222-
{/* Withdraw */}
223-
<Grid item xs={12} md={4}>
224-
<Typography variant="subtitle2" gutterBottom>Withdraw</Typography>
230+
{/* Withdraw */}
231+
{actionTab === 2 && (
232+
<Box sx={{ pt: 2, maxWidth: 480 }}>
225233
<TextField label="Amount (FULA)" value={withdrawAmount} onChange={(e) => setWithdrawAmount(e.target.value)}
226234
fullWidth size="small" type="number" />
227235
<Button size="small" variant="contained" color="secondary" sx={{ mt: 1 }}
@@ -231,8 +239,8 @@ function OwnerActions({ memberWallet }: { memberWallet: string }) {
231239
</Button>
232240
{withdrawSuccess && <Alert severity="success" sx={{ mt: 1 }}>Withdrawn!</Alert>}
233241
{withdrawError && <Alert severity="error" sx={{ mt: 1 }}>{formatContractError(withdrawError)}</Alert>}
234-
</Grid>
235-
</Grid>
242+
</Box>
243+
)}
236244

237245
<OnChainDisclaimer accepted={disclaimer} onChange={setDisclaimer} />
238246
</Paper>

src/app/programs/page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ function ProgramDetail({ programId }: { programId: number }) {
240240
const { data: transferLimit } = useTransferLimit(programId);
241241

242242
const isPA = role === MemberRoleEnum.ProgramAdmin;
243-
const canManageProgram = isAdmin;
243+
const canManageProgram = isAdmin || isPA;
244244
const canManageSubTypes = isAdmin || isPA;
245245
const canSetTransferLimit = isAdmin || isPA;
246246
const canAddMembers = isAdmin || isPA || role === MemberRoleEnum.TeamLeader;
@@ -601,7 +601,7 @@ function ProgramDetail({ programId }: { programId: number }) {
601601
{(isAdmin || canManageSubTypes) && program.active && (
602602
<Paper sx={{ p: 2, mb: 3 }}>
603603
<Typography variant="h6" gutterBottom>Reward Configuration</Typography>
604-
<RewardTypesSection isAdmin={isAdmin} />
604+
<RewardTypesSection isAdmin={isAdmin || isPA} />
605605
<SubTypesSection programId={programId} canManage={canManageSubTypes} />
606606
</Paper>
607607
)}

src/components/layout/Navigation.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import ReceiptLongIcon from "@mui/icons-material/ReceiptLong";
99
import AssessmentIcon from "@mui/icons-material/Assessment";
1010
import Link from "next/link";
1111
import { usePathname } from "next/navigation";
12+
import { useState, useEffect } from "react";
1213
import { useUserRole } from "@/hooks/useUserRole";
1314

1415
export const DRAWER_WIDTH = 240;
@@ -27,6 +28,8 @@ export function Navigation({ mobileOpen, onClose }: { mobileOpen: boolean; onClo
2728
const { isConnected } = useUserRole();
2829
const theme = useTheme();
2930
const isMobile = useMediaQuery(theme.breakpoints.down("md"));
31+
const [mounted, setMounted] = useState(false);
32+
useEffect(() => setMounted(true), []);
3033

3134
const drawerContent = (
3235
<>
@@ -45,7 +48,7 @@ export function Navigation({ mobileOpen, onClose }: { mobileOpen: boolean; onClo
4548
component={Link}
4649
href={item.href}
4750
selected={pathname === item.href || (item.href !== "/" && pathname.startsWith(item.href))}
48-
disabled={item.requiresAuth && !isConnected}
51+
disabled={mounted && item.requiresAuth && !isConnected}
4952
onClick={isMobile ? onClose : undefined}
5053
>
5154
<ListItemIcon>{item.icon}</ListItemIcon>

0 commit comments

Comments
 (0)