popsite-ui 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/App.jsx +95 -0
- package/README.md +92 -0
- package/components/layout/PortalHeader.jsx +18 -0
- package/components/layout/SystemSidebar.jsx +33 -0
- package/components/modules/AnalyticsDashboardModule.jsx +17 -0
- package/components/modules/ChatMessagingModule.jsx +17 -0
- package/components/modules/EcommerceStoreModule.jsx +17 -0
- package/components/modules/EventTicketBookingModule.jsx +17 -0
- package/components/modules/FlightBookingModule.jsx +17 -0
- package/components/modules/FoodOrderingModule.jsx +17 -0
- package/components/modules/HospitalAppointmentModule.jsx +17 -0
- package/components/modules/HotelBookingModule.jsx +17 -0
- package/components/modules/InvoiceBillingModule.jsx +17 -0
- package/components/modules/LibraryManagementModule.jsx +17 -0
- package/components/modules/ModuleContentDeck.jsx +44 -0
- package/components/modules/MovieBookingModule.jsx +17 -0
- package/components/modules/QuizExamModule.jsx +17 -0
- package/components/modules/StudentRegistrationModule.jsx +17 -0
- package/components/modules/SystemModuleRenderer.jsx +19 -0
- package/components/modules/SystemModuleTemplate.jsx +62 -0
- package/components/modules/SystemVisualWidget.jsx +123 -0
- package/components/modules/moduleContentMap.js +238 -0
- package/components/modules/moduleEnhancementsMap.js +439 -0
- package/components/modules/systemModuleMap.js +31 -0
- package/components/system/DynamicSystemForm.jsx +154 -0
- package/components/system/SystemHero.jsx +21 -0
- package/components/system/SystemSummaryCard.jsx +53 -0
- package/data/systems/analyticsDashboard.js +48 -0
- package/data/systems/chatMessaging.js +43 -0
- package/data/systems/ecommerceStore.js +50 -0
- package/data/systems/eventTicketBooking.js +50 -0
- package/data/systems/flightBooking.js +38 -0
- package/data/systems/foodOrdering.js +48 -0
- package/data/systems/hospitalAppointment.js +50 -0
- package/data/systems/hotelBooking.js +38 -0
- package/data/systems/index.js +31 -0
- package/data/systems/invoiceBilling.js +50 -0
- package/data/systems/libraryManagement.js +43 -0
- package/data/systems/movieBooking.js +48 -0
- package/data/systems/quizExam.js +38 -0
- package/data/systems/studentRegistration.js +43 -0
- package/dist/popsite-ui.es.js +4368 -0
- package/dist/popsite-ui.umd.js +60 -0
- package/dist/style.css +1 -0
- package/index.html +13 -0
- package/library/index.js +20 -0
- package/main.jsx +15 -0
- package/package.json +40 -0
- package/src/App.jsx +12 -0
- package/src/components/modules/AnalyticsDashboardModule.jsx +224 -0
- package/src/components/modules/ChatMessagingModule.jsx +294 -0
- package/src/components/modules/EcommerceStoreModule.jsx +405 -0
- package/src/components/modules/EventTicketBookingModule.jsx +253 -0
- package/src/components/modules/FlightBookingModule.jsx +399 -0
- package/src/components/modules/FoodOrderingModule.jsx +316 -0
- package/src/components/modules/HospitalAppointmentModule.jsx +267 -0
- package/src/components/modules/HotelBookingModule.jsx +317 -0
- package/src/components/modules/InvoiceBillingModule.jsx +302 -0
- package/src/components/modules/LandingPageModule.jsx +185 -0
- package/src/components/modules/LibraryManagementModule.jsx +189 -0
- package/src/components/modules/MovieBookingModule.jsx +337 -0
- package/src/components/modules/QuizExamModule.jsx +255 -0
- package/src/components/modules/StudentRegistrationModule.jsx +292 -0
- package/src/components/system/SystemHero.jsx +44 -0
- package/src/components/system/SystemSummaryCard.jsx +29 -0
- package/src/components/system/Toast.jsx +69 -0
- package/src/data/systems/analyticsDashboard.js +32 -0
- package/src/data/systems/chatMessaging.js +59 -0
- package/src/data/systems/ecommerceStore.js +84 -0
- package/src/data/systems/eventBooking.js +33 -0
- package/src/data/systems/flightBooking.js +59 -0
- package/src/data/systems/foodOrdering.js +48 -0
- package/src/data/systems/hospitalAppointment.js +48 -0
- package/src/data/systems/hotelBooking.js +59 -0
- package/src/data/systems/invoiceBilling.js +19 -0
- package/src/data/systems/landingPage.js +29 -0
- package/src/data/systems/libraryManagement.js +17 -0
- package/src/data/systems/movieBooking.js +49 -0
- package/src/data/systems/quizExam.js +31 -0
- package/src/data/systems/studentRegistration.js +9 -0
- package/src/index.js +22 -0
- package/src/main.jsx +10 -0
- package/src/styles.css +296 -0
- package/styles.css +820 -0
- package/utils/systemEngine.js +128 -0
- package/vite.config.js +8 -0
- package/vite.lib.config.js +27 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
const seatRows = ['A', 'B', 'C', 'D', 'E', 'F'];
|
|
4
|
+
const seatCols = [1, 2, 3, 4, 5, 6, 7, 8];
|
|
5
|
+
|
|
6
|
+
function SeatMapWidget({ title, occupiedSeats = [] }) {
|
|
7
|
+
return (
|
|
8
|
+
<article className="visual-widget">
|
|
9
|
+
<div className="visual-head">
|
|
10
|
+
<h4>{title || 'Seat Map'}</h4>
|
|
11
|
+
<span>{occupiedSeats.length} occupied</span>
|
|
12
|
+
</div>
|
|
13
|
+
<div className="seat-map-grid">
|
|
14
|
+
{seatRows.map((row) => (
|
|
15
|
+
<div className="seat-row" key={row}>
|
|
16
|
+
<small>{row}</small>
|
|
17
|
+
<div className="seat-row-cells">
|
|
18
|
+
{seatCols.map((col) => {
|
|
19
|
+
const seatId = `${row}${col}`;
|
|
20
|
+
const occupied = occupiedSeats.includes(seatId);
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<span key={seatId} className={`seat-cell ${occupied ? 'occupied' : 'available'}`}>
|
|
24
|
+
{seatId}
|
|
25
|
+
</span>
|
|
26
|
+
);
|
|
27
|
+
})}
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
))}
|
|
31
|
+
</div>
|
|
32
|
+
</article>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function RouteTimelineWidget({ title, points = [] }) {
|
|
37
|
+
return (
|
|
38
|
+
<article className="visual-widget">
|
|
39
|
+
<div className="visual-head">
|
|
40
|
+
<h4>{title || 'Route Timeline'}</h4>
|
|
41
|
+
<span>{points.length} points</span>
|
|
42
|
+
</div>
|
|
43
|
+
<div className="route-timeline">
|
|
44
|
+
{points.map((point, index) => (
|
|
45
|
+
<div key={`${point}-${index}`} className="route-point">
|
|
46
|
+
<span className="route-dot" />
|
|
47
|
+
<p>{point}</p>
|
|
48
|
+
</div>
|
|
49
|
+
))}
|
|
50
|
+
</div>
|
|
51
|
+
</article>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function OccupancyMeterWidget({ title, percentage = 0 }) {
|
|
56
|
+
const safePercentage = Math.max(0, Math.min(100, Number(percentage) || 0));
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<article className="visual-widget">
|
|
60
|
+
<div className="visual-head">
|
|
61
|
+
<h4>{title || 'Occupancy Meter'}</h4>
|
|
62
|
+
<span>{safePercentage}%</span>
|
|
63
|
+
</div>
|
|
64
|
+
<div className="meter-track">
|
|
65
|
+
<span className="meter-fill" style={{ width: `${safePercentage}%` }} />
|
|
66
|
+
</div>
|
|
67
|
+
<p className="meter-note">Real-time occupancy against available operational capacity.</p>
|
|
68
|
+
</article>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function KpiSparkCardsWidget({ title, cards = [] }) {
|
|
73
|
+
return (
|
|
74
|
+
<article className="visual-widget">
|
|
75
|
+
<div className="visual-head">
|
|
76
|
+
<h4>{title || 'KPI Spark Cards'}</h4>
|
|
77
|
+
<span>{cards.length} KPIs</span>
|
|
78
|
+
</div>
|
|
79
|
+
<div className="kpi-spark-grid">
|
|
80
|
+
{cards.map((card) => {
|
|
81
|
+
const maxTrend = Math.max(...card.trend, 1);
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<div className="kpi-card" key={card.label}>
|
|
85
|
+
<small>{card.label}</small>
|
|
86
|
+
<strong>{card.value}</strong>
|
|
87
|
+
<div className="spark-bars">
|
|
88
|
+
{card.trend.map((point, index) => (
|
|
89
|
+
<span
|
|
90
|
+
key={`${card.label}-${index}`}
|
|
91
|
+
style={{ height: `${Math.max(12, Math.round((point / maxTrend) * 38))}px` }}
|
|
92
|
+
/>
|
|
93
|
+
))}
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
);
|
|
97
|
+
})}
|
|
98
|
+
</div>
|
|
99
|
+
</article>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function SystemVisualWidget({ widget }) {
|
|
104
|
+
if (!widget || !widget.type) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (widget.type === 'seat-map') {
|
|
109
|
+
return <SeatMapWidget title={widget.title} occupiedSeats={widget.occupiedSeats} />;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (widget.type === 'route-timeline') {
|
|
113
|
+
return <RouteTimelineWidget title={widget.title} points={widget.points} />;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (widget.type === 'occupancy-meter') {
|
|
117
|
+
return <OccupancyMeterWidget title={widget.title} percentage={widget.percentage} />;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return <KpiSparkCardsWidget title={widget.title} cards={widget.cards || []} />;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export default SystemVisualWidget;
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
const moduleContentMap = {
|
|
2
|
+
'movie-booking': {
|
|
3
|
+
overview: 'Supports multiplex operations with show scheduling, seat category pricing, and high-conversion booking confirmation.',
|
|
4
|
+
quickStats: [
|
|
5
|
+
{ label: 'Peak Throughput', value: '2.1k bookings/hr' },
|
|
6
|
+
{ label: 'Average Checkout Time', value: '36 sec' },
|
|
7
|
+
{ label: 'Seat Utilization Target', value: '87%' }
|
|
8
|
+
],
|
|
9
|
+
workflowSteps: [
|
|
10
|
+
'Select title, date, and show slot',
|
|
11
|
+
'Apply seat category and seat count',
|
|
12
|
+
'Generate pricing and confirmation summary'
|
|
13
|
+
],
|
|
14
|
+
policyNotes: [
|
|
15
|
+
'Seat inventory should sync every 30 seconds with POS.',
|
|
16
|
+
'Recliner tier has dynamic pricing for weekend prime slots.',
|
|
17
|
+
'Cancellations allowed up to 20 minutes before show time.'
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
'flight-booking': {
|
|
21
|
+
overview: 'Designed for airline reservation workflows with route selection, fare class management, and passenger billing.',
|
|
22
|
+
quickStats: [
|
|
23
|
+
{ label: 'Routes Configured', value: '120+' },
|
|
24
|
+
{ label: 'Fare Repricing Window', value: '15 min' },
|
|
25
|
+
{ label: 'Average Ticket Value', value: '$420' }
|
|
26
|
+
],
|
|
27
|
+
workflowSteps: [
|
|
28
|
+
'Select origin, destination, and travel date',
|
|
29
|
+
'Configure passenger count and cabin class',
|
|
30
|
+
'Generate itinerary pricing summary'
|
|
31
|
+
],
|
|
32
|
+
policyNotes: [
|
|
33
|
+
'Business and First class include priority service fee.',
|
|
34
|
+
'Name corrections allowed within 24 hours of booking.',
|
|
35
|
+
'Publish fare updates to all channels every 5 minutes.'
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
'hotel-booking': {
|
|
39
|
+
overview: 'Built for property booking operations with room inventory classes, stay duration pricing, and guest management.',
|
|
40
|
+
quickStats: [
|
|
41
|
+
{ label: 'Rooms Managed', value: '480' },
|
|
42
|
+
{ label: 'Avg Stay Length', value: '2.8 nights' },
|
|
43
|
+
{ label: 'Occupancy Goal', value: '82%' }
|
|
44
|
+
],
|
|
45
|
+
workflowSteps: [
|
|
46
|
+
'Capture guest profile and city selection',
|
|
47
|
+
'Select room type, nights, and guest count',
|
|
48
|
+
'Generate reservation pricing breakdown'
|
|
49
|
+
],
|
|
50
|
+
policyNotes: [
|
|
51
|
+
'Suite category includes concierge package fee.',
|
|
52
|
+
'Early check-in is request based and property dependent.',
|
|
53
|
+
'Booking modifications lock 6 hours before check-in.'
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
'event-ticket-booking': {
|
|
57
|
+
overview: 'Supports event operations with access-zone tiers, attendee notes, and flexible pass allocation logic.',
|
|
58
|
+
quickStats: [
|
|
59
|
+
{ label: 'Events Supported', value: '65 per month' },
|
|
60
|
+
{ label: 'VIP Conversion', value: '24%' },
|
|
61
|
+
{ label: 'Avg Pass Bundle', value: '3.2 passes' }
|
|
62
|
+
],
|
|
63
|
+
workflowSteps: [
|
|
64
|
+
'Select event profile and event date',
|
|
65
|
+
'Assign pass count and zone category',
|
|
66
|
+
'Generate attendee and billing summary'
|
|
67
|
+
],
|
|
68
|
+
policyNotes: [
|
|
69
|
+
'Backstage zone requires manual organizer approval.',
|
|
70
|
+
'Digital pass QR generation happens post payment.',
|
|
71
|
+
'Special notes are visible to venue operations.'
|
|
72
|
+
]
|
|
73
|
+
},
|
|
74
|
+
'food-ordering': {
|
|
75
|
+
overview: 'Optimized for food delivery teams with order-item scaling, delivery SLA modes, and quick checkout totals.',
|
|
76
|
+
quickStats: [
|
|
77
|
+
{ label: 'Orders per Day', value: '11k+' },
|
|
78
|
+
{ label: 'Median Delivery SLA', value: '32 min' },
|
|
79
|
+
{ label: 'Repeat Rate', value: '41%' }
|
|
80
|
+
],
|
|
81
|
+
workflowSteps: [
|
|
82
|
+
'Select restaurant and delivery schedule',
|
|
83
|
+
'Choose item count and delivery type',
|
|
84
|
+
'Generate customer order and amount summary'
|
|
85
|
+
],
|
|
86
|
+
policyNotes: [
|
|
87
|
+
'Priority orders are auto-routed to nearest kitchen hub.',
|
|
88
|
+
'Express mode includes surge multiplier during peak hours.',
|
|
89
|
+
'Order holds expire if checkout is inactive for 7 minutes.'
|
|
90
|
+
]
|
|
91
|
+
},
|
|
92
|
+
'ecommerce-store': {
|
|
93
|
+
overview: 'Supports catalog commerce operations with quantity-based pricing, delivery plans, and checkout detail capture.',
|
|
94
|
+
quickStats: [
|
|
95
|
+
{ label: 'SKUs Listed', value: '95k' },
|
|
96
|
+
{ label: 'Cart to Order Rate', value: '14.7%' },
|
|
97
|
+
{ label: 'Avg Order Value', value: '$73' }
|
|
98
|
+
],
|
|
99
|
+
workflowSteps: [
|
|
100
|
+
'Capture customer and product category',
|
|
101
|
+
'Select quantity and delivery plan',
|
|
102
|
+
'Generate checkout total with service fees'
|
|
103
|
+
],
|
|
104
|
+
policyNotes: [
|
|
105
|
+
'Same day option is restricted by fulfillment zone.',
|
|
106
|
+
'Prime plans receive shipping fee concessions.',
|
|
107
|
+
'Address notes are mandatory for high-value shipments.'
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
'library-management': {
|
|
111
|
+
overview: 'Built for academic and enterprise libraries with issue duration handling, membership classes, and service fees.',
|
|
112
|
+
quickStats: [
|
|
113
|
+
{ label: 'Active Members', value: '8,400' },
|
|
114
|
+
{ label: 'Daily Issues', value: '630' },
|
|
115
|
+
{ label: 'On-time Returns', value: '89%' }
|
|
116
|
+
],
|
|
117
|
+
workflowSteps: [
|
|
118
|
+
'Capture librarian and member context',
|
|
119
|
+
'Assign book category and borrow duration',
|
|
120
|
+
'Generate issue summary with service amount'
|
|
121
|
+
],
|
|
122
|
+
policyNotes: [
|
|
123
|
+
'Scholar membership offers reduced daily service rates.',
|
|
124
|
+
'Borrow period extension requires librarian approval.',
|
|
125
|
+
'Penalty policy applies after grace period expiry.'
|
|
126
|
+
]
|
|
127
|
+
},
|
|
128
|
+
'student-registration': {
|
|
129
|
+
overview: 'Covers university intake operations including program registration, semester-wise fees, and student profile validation.',
|
|
130
|
+
quickStats: [
|
|
131
|
+
{ label: 'Registrations per Intake', value: '5,200' },
|
|
132
|
+
{ label: 'Completion Rate', value: '92%' },
|
|
133
|
+
{ label: 'Avg Processing Time', value: '4.5 min' }
|
|
134
|
+
],
|
|
135
|
+
workflowSteps: [
|
|
136
|
+
'Capture student identity and contact profile',
|
|
137
|
+
'Assign course, semester, and registration type',
|
|
138
|
+
'Generate enrollment charge summary'
|
|
139
|
+
],
|
|
140
|
+
policyNotes: [
|
|
141
|
+
'International applications require additional verification.',
|
|
142
|
+
'Semester fee slabs vary by program group.',
|
|
143
|
+
'Profiles remain editable until enrollment lock date.'
|
|
144
|
+
]
|
|
145
|
+
},
|
|
146
|
+
'hospital-appointment': {
|
|
147
|
+
overview: 'Designed for healthcare scheduling with department routing, consultation modes, and appointment pricing controls.',
|
|
148
|
+
quickStats: [
|
|
149
|
+
{ label: 'Appointments per Day', value: '1,350' },
|
|
150
|
+
{ label: 'Telehealth Share', value: '27%' },
|
|
151
|
+
{ label: 'Avg Wait Time', value: '18 min' }
|
|
152
|
+
],
|
|
153
|
+
workflowSteps: [
|
|
154
|
+
'Capture patient and department details',
|
|
155
|
+
'Select appointment date, slots, and mode',
|
|
156
|
+
'Generate consultation billing summary'
|
|
157
|
+
],
|
|
158
|
+
policyNotes: [
|
|
159
|
+
'Priority mode reserves dedicated physician slots.',
|
|
160
|
+
'Symptoms notes are shared only with assigned clinicians.',
|
|
161
|
+
'No-show policy applies after 10-minute grace window.'
|
|
162
|
+
]
|
|
163
|
+
},
|
|
164
|
+
'invoice-billing': {
|
|
165
|
+
overview: 'Supports financial operations with billable unit computation, plan-based rates, and invoice-ready summaries.',
|
|
166
|
+
quickStats: [
|
|
167
|
+
{ label: 'Invoices per Month', value: '3,900' },
|
|
168
|
+
{ label: 'Collection Rate', value: '94%' },
|
|
169
|
+
{ label: 'Average Invoice Size', value: '$1,280' }
|
|
170
|
+
],
|
|
171
|
+
workflowSteps: [
|
|
172
|
+
'Capture client and service type',
|
|
173
|
+
'Assign billing plan and billable units',
|
|
174
|
+
'Generate invoice total with service fee'
|
|
175
|
+
],
|
|
176
|
+
policyNotes: [
|
|
177
|
+
'Retainer plans are reconciled at month-end cycles.',
|
|
178
|
+
'Project billing can include milestone surcharge.',
|
|
179
|
+
'Invoices are immutable after accounting approval.'
|
|
180
|
+
]
|
|
181
|
+
},
|
|
182
|
+
'chat-messaging': {
|
|
183
|
+
overview: 'Built for communication suite onboarding with user-seat scaling, plan tiers, and support window setup.',
|
|
184
|
+
quickStats: [
|
|
185
|
+
{ label: 'Messages per Day', value: '4.8M' },
|
|
186
|
+
{ label: 'Avg Session Duration', value: '21 min' },
|
|
187
|
+
{ label: 'Enterprise Adoption', value: '38%' }
|
|
188
|
+
],
|
|
189
|
+
workflowSteps: [
|
|
190
|
+
'Capture workspace and ownership details',
|
|
191
|
+
'Configure seat count and support windows',
|
|
192
|
+
'Generate subscription pricing summary'
|
|
193
|
+
],
|
|
194
|
+
policyNotes: [
|
|
195
|
+
'Enterprise plans include audit and retention controls.',
|
|
196
|
+
'24x7 support is available only on Business and above.',
|
|
197
|
+
'Seat changes are prorated in the next billing cycle.'
|
|
198
|
+
]
|
|
199
|
+
},
|
|
200
|
+
'analytics-dashboard': {
|
|
201
|
+
overview: 'Supports analytics platform setup with source scaling, refresh windows, and analyst seat planning.',
|
|
202
|
+
quickStats: [
|
|
203
|
+
{ label: 'Pipelines Monitored', value: '1,100+' },
|
|
204
|
+
{ label: 'Dashboard Refresh SLA', value: '99.9%' },
|
|
205
|
+
{ label: 'Avg Active Analysts', value: '64' }
|
|
206
|
+
],
|
|
207
|
+
workflowSteps: [
|
|
208
|
+
'Define dashboard type and source volume',
|
|
209
|
+
'Configure refresh cadence and seat count',
|
|
210
|
+
'Generate platform usage and pricing summary'
|
|
211
|
+
],
|
|
212
|
+
policyNotes: [
|
|
213
|
+
'Hourly refresh requires Pro tier or above.',
|
|
214
|
+
'Elite plan enables higher source connection caps.',
|
|
215
|
+
'Data source onboarding includes schema validation checks.'
|
|
216
|
+
]
|
|
217
|
+
},
|
|
218
|
+
'quiz-exam': {
|
|
219
|
+
overview: 'Created for digital assessment operations with candidate volume planning, exam modes, and pricing outputs.',
|
|
220
|
+
quickStats: [
|
|
221
|
+
{ label: 'Exams Conducted', value: '860 per term' },
|
|
222
|
+
{ label: 'Candidate Capacity', value: '2,000 per exam' },
|
|
223
|
+
{ label: 'Proctored Adoption', value: '56%' }
|
|
224
|
+
],
|
|
225
|
+
workflowSteps: [
|
|
226
|
+
'Configure exam identity and schedule',
|
|
227
|
+
'Set question count, candidate volume, and mode',
|
|
228
|
+
'Generate exam delivery cost summary'
|
|
229
|
+
],
|
|
230
|
+
policyNotes: [
|
|
231
|
+
'Certification mode enforces stricter identity checks.',
|
|
232
|
+
'Question bank versioning is mandatory for compliance.',
|
|
233
|
+
'Late join policy can be enabled per exam mode.'
|
|
234
|
+
]
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
export default moduleContentMap;
|