forked from UKSOURCE/cms.lams
feat(cms): implement structured tuition data normalization and editor
Refactor tuition data from a simple numeric array to a structured object containing time labels and values. This allows for more flexible charting and precise data entry in the CMS. - Add `normalizeTuition`, `normalizeTuitionSeries`, and `normalizeTuitionPoint` to `admissionsController.js` - Update `admissionsConfig.js` to use `objectList` for tuition data points instead of `stringList` - Migrate existing tuition data in `admissions.json` to the new structured format - Fix duplicate text in `admissions.json` grant amounts and descriptions
This commit is contained in:
@@ -66,6 +66,50 @@ function normalizeCalculator(calculator) {
|
||||
return nextCalculator;
|
||||
}
|
||||
|
||||
function normalizeTuitionPoint(point, index) {
|
||||
if (point && typeof point === "object" && !Array.isArray(point)) {
|
||||
const numericValue = Number(point.value);
|
||||
return {
|
||||
time: String(point.time || point.label || `Year ${index + 1}`),
|
||||
value: Number.isFinite(numericValue) && numericValue >= 0 ? numericValue : 0,
|
||||
};
|
||||
}
|
||||
|
||||
const numericValue = Number(point);
|
||||
return {
|
||||
time: `Year ${index + 1}`,
|
||||
value: Number.isFinite(numericValue) && numericValue >= 0 ? numericValue : 0,
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeTuitionSeries(series, index) {
|
||||
const source = typeof series === "string" ? { label: series } : { ...(series || {}) };
|
||||
const rawPoints = Array.isArray(source.points) && source.points.length
|
||||
? source.points
|
||||
: Array.isArray(source.values)
|
||||
? source.values
|
||||
: [];
|
||||
|
||||
return {
|
||||
label: String(source.label || `Series ${index + 1}`).slice(0, 40),
|
||||
color: String(source.color || "#0F172A"),
|
||||
points: rawPoints.map(normalizeTuitionPoint),
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeTuition(tuition) {
|
||||
const nextTuition = { ...(tuition || {}) };
|
||||
|
||||
nextTuition.title = String(nextTuition.title || "");
|
||||
nextTuition.chartTitle = String(nextTuition.chartTitle || "");
|
||||
nextTuition.chartDescription = String(nextTuition.chartDescription || "");
|
||||
nextTuition.series = Array.isArray(nextTuition.series)
|
||||
? nextTuition.series.map(normalizeTuitionSeries)
|
||||
: [];
|
||||
|
||||
return nextTuition;
|
||||
}
|
||||
|
||||
function normalizeAdmissionsPayload(rawPayload) {
|
||||
const payload = JSON.parse(JSON.stringify(rawPayload || {}));
|
||||
|
||||
@@ -78,7 +122,7 @@ function normalizeAdmissionsPayload(rawPayload) {
|
||||
id: "eligibility",
|
||||
};
|
||||
payload.tuition = {
|
||||
...(payload.tuition || {}),
|
||||
...normalizeTuition(payload.tuition),
|
||||
id: "tuition-breakdown",
|
||||
};
|
||||
payload.keyDates = {
|
||||
|
||||
+43
-12
@@ -72,22 +72,53 @@
|
||||
{
|
||||
"label": "Traditional University",
|
||||
"color": "#850f0f",
|
||||
"values": [
|
||||
25000,
|
||||
49998,
|
||||
30000,
|
||||
100000,
|
||||
120000
|
||||
"points": [
|
||||
{
|
||||
"time": "Year 1",
|
||||
"value": 25000
|
||||
},
|
||||
{
|
||||
"time": "Year 2",
|
||||
"value": 49998
|
||||
},
|
||||
{
|
||||
"time": "Year 3",
|
||||
"value": 30000
|
||||
},
|
||||
{
|
||||
"time": "Year 4",
|
||||
"value": 100000
|
||||
},
|
||||
{
|
||||
"time": "Year 5",
|
||||
"value": 120000
|
||||
},
|
||||
{
|
||||
"time": "Year 6",
|
||||
"value": 500000
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "LAMS",
|
||||
"color": "#a700b3",
|
||||
"values": [
|
||||
3588,
|
||||
7176,
|
||||
10764,
|
||||
10000
|
||||
"points": [
|
||||
{
|
||||
"time": "Year 1",
|
||||
"value": 3588
|
||||
},
|
||||
{
|
||||
"time": "Year 2",
|
||||
"value": 7176
|
||||
},
|
||||
{
|
||||
"time": "Year 3",
|
||||
"value": 10764
|
||||
},
|
||||
{
|
||||
"time": "Year 4",
|
||||
"value": 10000
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -195,7 +226,7 @@
|
||||
"items": [
|
||||
{
|
||||
"title": "Working Adult GrantWorking Adult GrantWorking Adul",
|
||||
"amount": "Up to $1,500Up to $1,500",
|
||||
"amount": "Up to $1,500",
|
||||
"description": "For students employed full-time while studying.For students employed full-time while studying.For students employed full-time while studying.For students employ"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -114,12 +114,30 @@ module.exports = {
|
||||
[
|
||||
text("label", "Series label", { maxLength: 40 }),
|
||||
{ key: "color", label: "Series color", type: "color" },
|
||||
stringList("values", "Data points", {
|
||||
itemLabel: "Point",
|
||||
fieldType: "number",
|
||||
min: 0,
|
||||
sortable: true,
|
||||
}),
|
||||
objectList(
|
||||
"points",
|
||||
"Data points",
|
||||
[
|
||||
text("time", "Time label", {
|
||||
maxLength: 30,
|
||||
placeholder: "Year 1",
|
||||
}),
|
||||
{
|
||||
key: "value",
|
||||
label: "Value",
|
||||
type: "number",
|
||||
min: 0,
|
||||
},
|
||||
],
|
||||
{
|
||||
itemLabel: "Point",
|
||||
sortable: true,
|
||||
itemTitleKey: "time",
|
||||
itemSubtitleKey: "value",
|
||||
helpText: "Each chart point requires both a time label and a numeric value.",
|
||||
emptyText: "No data points yet.",
|
||||
},
|
||||
),
|
||||
],
|
||||
{
|
||||
itemLabel: "Series",
|
||||
|
||||
Reference in New Issue
Block a user