Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | 3x 50x 50x 50x 1x 49x 48x 48x 50x 50x 50x 50x 50x 50x 50x | import Alert from "@mui/material/Alert";
import AlertTitle from "@mui/material/AlertTitle";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import LinearProgress from "@mui/material/LinearProgress";
import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";
import { alpha, useTheme } from "@mui/material/styles";
import useTeacherMadeAssignmentQuota from "@/utils/hooks/useTeacherMadeAssignmentQuota";
import SoftChip from "@/utils/components/feature-access/SoftChip";
/**
* Quota summary for the class Assignments tab (limit is per class, per teacher).
* @param {number|null} classAssignmentCount Assignments in the current class; omit for plan-only display.
*/
const TeacherMadeAssignmentQuotaBanner = ({ classAssignmentCount = null, sx }) => {
const theme = useTheme();
const { quota, ui, loading, openUpgradeOnBlock } = useTeacherMadeAssignmentQuota(classAssignmentCount);
if (loading && !quota) {
return (
<Box sx={{ width: "100%", ...sx }}>
<LinearProgress />
</Box>
);
}
if (!quota) return null;
const isUnlimited = quota.max_assignments === null;
const hasLimit = quota.max_assignments != null && quota.max_assignments > 0;
const usagePercent = hasLimit ? Math.min(100, (quota.current_count / quota.max_assignments) * 100) : 0;
const atLimit = hasLimit && !quota.can_create;
// A full class also reports can_create: false, so `atLimit` has to win here —
// otherwise a teacher who used all 10 slots was told assignments were not part
// of their plan, and the at-limit copy below was unreachable.
const isBlocked = !atLimit && (quota.max_assignments === 0 || !quota.can_create);
const severity = isBlocked || atLimit ? "warning" : isUnlimited ? "success" : "info";
const title = isBlocked
? "Assignment creation not included in your plan"
: atLimit
? "Assignment limit reached in this class"
: isUnlimited
? "Unlimited assignment creation"
: "Teacher-made assignments (this class)";
const description = isBlocked
? "Upgrade your district plan to create assignments in your classes."
: atLimit
? `You have used all ${quota.max_assignments} assignment slots in this class. Delete one to create another, or upgrade for unlimited assignments per class.`
: isUnlimited
? "Your plan allows unlimited teacher-made assignments in each class."
: `You can create ${quota.remaining ?? 0} more in this class (${quota.current_count} of ${quota.max_assignments} used). Each class has its own limit.`;
return (
<Alert
severity={severity}
variant="outlined"
sx={{
width: "100%",
alignItems: "flex-start",
bgcolor: alpha(theme.palette[severity].main, theme.palette.mode === "light" ? 0.06 : 0.12),
...sx,
}}
action={
ui.upgradeRequired ? (
<Button
color="warning"
size="small"
variant="soft"
onClick={openUpgradeOnBlock}
sx={{ fontWeight: 600 }}
>
Upgrade
</Button>
) : null
}
>
<AlertTitle sx={{ mb: 0.5 }}>{title}</AlertTitle>
<Stack spacing={1.25}>
<Typography variant="body2">{description}</Typography>
{hasLimit && (
<Box sx={{ width: "100%", maxWidth: 420 }}>
<Box sx={{ display: "flex", justifyContent: "space-between", mb: 0.5 }}>
<Typography variant="caption" color="text.secondary">
This class
</Typography>
<SoftChip
size="sm"
color={atLimit ? "warning" : "info"}
label={`${quota.current_count} / ${quota.max_assignments}`}
/>
</Box>
<LinearProgress
variant="determinate"
value={usagePercent}
color={atLimit ? "warning" : "primary"}
sx={{ height: 8, borderRadius: 1 }}
/>
</Box>
)}
{isUnlimited && (
<SoftChip
size="sm"
color="success"
label="No per-class cap on your plan"
sx={{ alignSelf: "flex-start" }}
/>
)}
</Stack>
</Alert>
);
};
export default TeacherMadeAssignmentQuotaBanner;
|