Skip to content

Allow bulk creation of SCE events using CSV files - #2181

Open
ethanccheng wants to merge 4 commits into
SCE-Development:devfrom
ethanccheng:feature/create-events-thru-csv
Open

Allow bulk creation of SCE events using CSV files#2181
ethanccheng wants to merge 4 commits into
SCE-Development:devfrom
ethanccheng:feature/create-events-thru-csv

Conversation

@ethanccheng

Copy link
Copy Markdown
Screenshot 2026-08-12 225314
Recording.2026-08-12.151451.mp4

Features: Adds import CSV option to create SCE events page. Displays table for data upon file upload. Click create events to publish all events in CSV file. Currently no support for adding registration questions or adding other event admins.

Image is example of a CSV file to create SCE events. Must include headers and each row is a single event. Date and time must be in the same format shown and publish status + visibility must be lowercase. To disable waitlist, put -1 as value. Publish date can be left empty if N/A.

Comment thread src/Pages/Events/CreateEventPage.js Outdated
if (!file) return;

if (file.size > maxFileSize) {
alert('File size exceeds the 10MB limit.');

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use

export default function ConfirmationModal(props) {

also in the message, include how many bytes the file is like

file is size 1234567, this exceeds the 10MB upload limit


async function handleFileCreateEvent() {
for (const row of values) {
const waitlistValue = Number(row[6]);

@evanugarte evanugarte Aug 13, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we be 100% sure that the row has at least 7 elements? like a small if statement,

and small comment for what each column means like

date,title,description,...

otherwise this happens

a = []
a[4] // undefined

@ethanccheng
ethanccheng force-pushed the feature/create-events-thru-csv branch from ca08f66 to f303f37 Compare August 17, 2026 21:13
@ethanccheng

Copy link
Copy Markdown
Author
image image

First image: warning if any elements in any rows are missing
Second image: warning if any required headers are missing

@evanugarte evanugarte left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets also add some screenshots for what the confirm/error modals look like

tysm for this

}
let missingElements = [];
for (let i = 0; i < row.length; i++) {
if (i !== 9 && row[i] === '') {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we leave a comment here on why index 9 is treated differently?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment thread src/Pages/Events/CreateEventPage.js Outdated
Comment on lines +339 to +347
setFileData([]);
setHeadersArray([]);
setValues([]);
const actualHeaders = (headersArray[0] || []).map((h) => h.trim());
const missingHeaders = EXPECTED_HEADERS.filter((h) => !actualHeaders.includes(h));
setModalWarningMessage(`Missing required columns: ${missingHeaders.join(', ')}`);
setConfirmModal(true);
isFileUpload.current = false;
return;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could this be its own function

that clears the data and shows the modal, this helper function could take th emodal warning message a parameter, lmk if this makes sense

its cause we have the same reset logic below for emptyValueCounter > 0

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@ethanccheng

Copy link
Copy Markdown
Author

lets also add some screenshots for what the confirm/error modals look like

I am confused by exactly what modals you want screenshots of besides the ones I already posted. Is there supposed to be another modal I need to add elsewhere?

@evanugarte evanugarte left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a way we can have an "example csv" that we can download for users to start filling out

like a button called "download example csv", the csv has all the columns

@steeevin88 steeevin88 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for making this PR! feel free to push back on any of these comments this was just a quick scan

also one more thing --> would it be helpful to have unit tests / an E2E test suite for this specific feature? just to make sure it doesn't break in the future... not sure if similar tests exists for SCEvents in Clark but it would be cool to have + ensure reliabiltiy of this feature in the future!

Comment on lines +303 to +306
const EXPECTED_HEADERS = [
'Event Name', 'Date', 'Time', 'Location', 'Description',
'Max Attendees', 'Waitlist', 'Publish Status', 'Visibility', 'Publish Date',
];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it maybe possible to link/sync this to the existing types? in case long term the fields to create an Event change (ex. new field is added), these EXPECTED_HEADERS would become outdated right?

if it's not possible no worries, just a consideration

}

function handleFileUpload(event) {
const maxFileSize = 10 * 1024 * 1024;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: what is this value? obviously not super hard to figure out but maybe leave a comment denoting what this is so people in the future don't need to do the mental math 😓

let missingElements = [];
for (let i = 0; i < row.length; i++) {
// index 9 is treated different because it is the only one that can be accepted as empty
if (i !== 9 && row[i] === '') {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we maybe make a row to field mapping/enum? it's not super clear what "index 9" is + to figure it out requires looking through the potential many columns in the expected CSV format, it'd be nice to know what it is through code (variable naming)

[6] - string - waitlist
[7] - string - publish status
[8] - string - visibility
[9] - string - publish date

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 on the enum, this comment is helpful but it might be just more clear if there's an explicity defined enum atop the file? or maybe not lol your call!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants