From 56a1150f0f283a45166ff7f3374497bc9c5915c3 Mon Sep 17 00:00:00 2001
From: gdjolt8
Date: Thu, 25 Sep 2025 17:38:17 -0400
Subject: [PATCH 01/10] added keyword + tag edit
---
src/components/ui/buttons/LoginButton.tsx | 2 +-
src/components/ui/forms/FormTagSelect.tsx | 2 +-
src/components/ui/forms/FormTextField.tsx | 16 +--
src/contexts/UserProvider.tsx | 2 +-
.../admin/components/OrgApproval.tsx | 18 ++-
src/modules/stuyactivities/admin/index.tsx | 2 +-
.../admin/pages/ApprovePending.tsx | 7 +-
.../stuyactivities/orgs/components/OrgNav.tsx | 34 ++---
.../orgs/org_admin/components/OrgEditor.tsx | 124 +++++++++++++++---
.../stuyactivities/orgs/org_admin/index.tsx | 2 +-
10 files changed, 151 insertions(+), 58 deletions(-)
diff --git a/src/components/ui/buttons/LoginButton.tsx b/src/components/ui/buttons/LoginButton.tsx
index c421358b..5de4cf58 100644
--- a/src/components/ui/buttons/LoginButton.tsx
+++ b/src/components/ui/buttons/LoginButton.tsx
@@ -12,7 +12,7 @@ const LoginButton = ({ onMouseEnter, onMouseLeave }: LoginButtonProps) => {
const { error } = await supabase.auth.signInWithOAuth({
provider: "google",
options: {
- redirectTo: PUBLIC_URL,
+ redirectTo: "http://localhost:3000",
},
});
if (error) {
diff --git a/src/components/ui/forms/FormTagSelect.tsx b/src/components/ui/forms/FormTagSelect.tsx
index 88f395d7..ecafbfdf 100644
--- a/src/components/ui/forms/FormTagSelect.tsx
+++ b/src/components/ui/forms/FormTagSelect.tsx
@@ -78,7 +78,7 @@ const FormTagSelect = ({
onChange={valueChanged}
value={value}
options={tags}
- renderTags={(value, props) => {
+ renderTags={(value: string[], props) => {
return value.map((option, index) => (
));
diff --git a/src/components/ui/forms/FormTextField.tsx b/src/components/ui/forms/FormTextField.tsx
index 75bce774..f6057a0a 100644
--- a/src/components/ui/forms/FormTextField.tsx
+++ b/src/components/ui/forms/FormTextField.tsx
@@ -80,7 +80,7 @@ const FormTextField = ({
const textChanged = (event: ChangeEvent) => {
let targetValue = event.target.value;
-
+ console.log(`changed to ${targetValue}`, requirements!);
if (
requirements?.maxChar &&
targetValue.length > requirements.maxChar
@@ -129,7 +129,7 @@ const FormTextField = ({
let countChars = false;
if (requirements.minChar) {
countChars = true;
- helperText += `: min ${requirements.minChar} Characters`;
+ helperText += `: Minimum ${requirements.minChar} Characters`;
}
if (requirements.maxChar) {
@@ -140,10 +140,10 @@ const FormTextField = ({
}
countChars = true;
- helperText += ` max ${requirements.maxChar} Characters`;
+ helperText += `Maximum ${requirements.maxChar} Characters`;
}
- if (countChars) helperText += `, at ${value?.length || 0}.`;
+ if (countChars) helperText += ` (${value?.length || 0}/${requirements.maxChar}.`;
let countWords = false;
@@ -153,7 +153,7 @@ const FormTextField = ({
}
countWords = true;
- helperText += ` min ${requirements.minWords} Words`;
+ helperText += ` Minimum ${requirements.minWords} Words`;
}
if (requirements.maxWords) {
@@ -162,15 +162,15 @@ const FormTextField = ({
}
if (countWords) {
- helperText += " to";
+ helperText += " to ";
}
countWords = true;
- helperText += ` max ${requirements.maxWords} Words`;
+ helperText += `Maximum ${requirements.maxWords} Words`;
}
if (countWords)
- helperText += `, at ${value?.trim().split(" ").length || 0}.`;
+ helperText += ` (${value?.trim().split(" ").length || 0}/${requirements.maxWords})`;
}
return (
diff --git a/src/contexts/UserProvider.tsx b/src/contexts/UserProvider.tsx
index db737f86..30c88ce1 100644
--- a/src/contexts/UserProvider.tsx
+++ b/src/contexts/UserProvider.tsx
@@ -201,4 +201,4 @@ const UserProvider = ({ children }: { children: React.ReactNode }) => {
);
};
-export default UserProvider;
+export default UserProvider;
\ No newline at end of file
diff --git a/src/modules/stuyactivities/admin/components/OrgApproval.tsx b/src/modules/stuyactivities/admin/components/OrgApproval.tsx
index 08f81ea6..ccdb1f0c 100644
--- a/src/modules/stuyactivities/admin/components/OrgApproval.tsx
+++ b/src/modules/stuyactivities/admin/components/OrgApproval.tsx
@@ -18,7 +18,10 @@ const OrgApproval = ({
} & Partial) => {
const { enqueueSnackbar } = useSnackbar();
const [buttonsDisabled, setButtonsDisabled] = useState(false);
-
+ const creator = org.memberships?.find((m) => m.role === 'CREATOR');
+ let keywords = org.keywords?.split(",");
+ console.log(keywords);
+ console.log(creator);
const approve = async () => {
setButtonsDisabled(true);
const { error } = await supabase.functions.invoke(
@@ -163,7 +166,12 @@ const OrgApproval = ({
Keywords
- {org.keywords || "none"}
+ {!org.keywords && none
}
+ {org.keywords &&
+ keywords?.map((n, _) => (
+ {(["AI", "AP", "CS", "GSA"]).includes(n.toUpperCase()) ? n.toUpperCase() : n[0].toUpperCase() + n.slice(1)}
+ ))
+ }
Tags
@@ -175,11 +183,9 @@ const OrgApproval = ({
Creator
+ {creator?.users?.first_name} {" "} {creator?.users?.last_name}
- {
- org.memberships?.find((m) => m.role === "CREATOR")
- ?.users?.email
- }
+ {creator?.users?.email}
diff --git a/src/modules/stuyactivities/admin/index.tsx b/src/modules/stuyactivities/admin/index.tsx
index abcfe70d..5b719539 100644
--- a/src/modules/stuyactivities/admin/index.tsx
+++ b/src/modules/stuyactivities/admin/index.tsx
@@ -140,4 +140,4 @@ const AdminRouter = () => {
);
};
-export default AdminRouter;
+export default AdminRouter;
\ No newline at end of file
diff --git a/src/modules/stuyactivities/admin/pages/ApprovePending.tsx b/src/modules/stuyactivities/admin/pages/ApprovePending.tsx
index 94986c3b..e7a7d889 100644
--- a/src/modules/stuyactivities/admin/pages/ApprovePending.tsx
+++ b/src/modules/stuyactivities/admin/pages/ApprovePending.tsx
@@ -56,8 +56,11 @@ const ApprovePending = () => {
)
)
`,
- )
- .eq("state", "PENDING");
+ ).order('id', {ascending:true});
+
+ const count = (await supabase.from("organizations").select('*').order('id', {ascending: true})).data;
+ console.log(count![0]);
+
if (error || !data) {
return enqueueSnackbar(
diff --git a/src/modules/stuyactivities/orgs/components/OrgNav.tsx b/src/modules/stuyactivities/orgs/components/OrgNav.tsx
index beaeef7c..488676e2 100644
--- a/src/modules/stuyactivities/orgs/components/OrgNav.tsx
+++ b/src/modules/stuyactivities/orgs/components/OrgNav.tsx
@@ -1,5 +1,5 @@
import React, { useContext, useState } from "react";
-import { Box, List } from "@mui/material";
+import { List } from "@mui/material";
import OrgContext from "../../../../contexts/OrgContext";
import { useLocation, useNavigate } from "react-router-dom";
import UserContext from "../../../../contexts/UserContext";
@@ -68,9 +68,9 @@ const OrgNav = ({ isMobile }: { isMobile: boolean }) => {
const renderDesktopList = (links: LinkItem[]) => (
{links.map((linkData, i) => (
- {
>
{linkData.display}
-
+
))}
);
@@ -96,7 +96,7 @@ const OrgNav = ({ isMobile }: { isMobile: boolean }) => {
links.map((linkData, i) => (
-
-
+
+
About
-
+
{renderMobileButtons(navLinks)}
{adminLinks.length > 0 && (
<>
-
+
Admin Tools
-
+
{renderMobileButtons(adminLinks)}
>
)}
@@ -185,4 +177,4 @@ const OrgNav = ({ isMobile }: { isMobile: boolean }) => {
);
};
-export default OrgNav;
+export default OrgNav;
\ No newline at end of file
diff --git a/src/modules/stuyactivities/orgs/org_admin/components/OrgEditor.tsx b/src/modules/stuyactivities/orgs/org_admin/components/OrgEditor.tsx
index 7dac43b4..a08e8576 100644
--- a/src/modules/stuyactivities/orgs/org_admin/components/OrgEditor.tsx
+++ b/src/modules/stuyactivities/orgs/org_admin/components/OrgEditor.tsx
@@ -1,5 +1,5 @@
import { ReactNode, useCallback, useEffect, useState } from "react";
-import { Avatar, Box, Paper } from "@mui/material";
+import { Avatar, Box, Paper, useMediaQuery } from "@mui/material";
import { useSnackbar } from "notistack";
import FormTextField from "../../../../../components/ui/forms/FormTextField";
import OrgRequirements from "../../../../../utils/OrgRequirements";
@@ -8,6 +8,9 @@ import { supabase } from "../../../../../lib/supabaseClient";
import { PUBLIC_URL } from "../../../../../config/constants";
import { useNavigate } from "react-router-dom";
import AsyncButton from "../../../../../components/ui/buttons/AsyncButton";
+import FormTagSelect from "../../../../../components/ui/forms/FormTagSelect";
+import FormSection from "../../../../../components/ui/forms/FormSection";
+import FormChipText from "../../../../../components/ui/forms/FormChipText";
type Props = {
organization: Partial
; // Make organization a prop to allow component to become reusable
@@ -28,6 +31,12 @@ type FormStatus = {
type orgKey = keyof OrganizationEdit & keyof Organization;
+function formatStr(a: string | string[] | undefined) {
+ let final_value = a;
+ final_value = (typeof a == "object" ?
+ Array.from(a).join('\n') : a)
+ return final_value;
+}
const EditField = ({
field,
pending,
@@ -127,6 +136,17 @@ const hiddenFields: string[] = [
"picture", // picture field has custom logic
];
+function arraysEqual(a: string[], b: string[]) {
+ if (a === b) return true;
+ if (a == null || b == null) return false;
+ if (a.length !== b.length) return false;
+
+ for (let i = 0; i < a.length; i++) {
+ if (a[i] !== b[i]) return false;
+ }
+ return true;
+}
+
/*
TextField Statuses:
- default is Approved
@@ -142,7 +162,7 @@ const OrgEditor = ({
setPendingEdit,
}: Props) => {
const { enqueueSnackbar } = useSnackbar();
-
+ const isMobile = useMediaQuery("(max-width: 640px)");
/* everything that is displayed on the page (could include values similar to original)*/
const [editData, setEditData] = useState({});
@@ -156,9 +176,11 @@ const OrgEditor = ({
File | null | undefined | string
>();
+ const [editTags, setEditTags] = useState(null);
+
const oldPicture =
existingEdit["picture"] === undefined ||
- existingEdit["picture"] === null
+ existingEdit["picture"] === null
? organization["picture"]
: existingEdit["picture"];
@@ -176,6 +198,11 @@ const OrgEditor = ({
return;
}
+ if (editTags !== null && !arraysEqual(editTags, organization.tags!)) {
+ setSavable(true);
+ return;
+ }
+
/* check if there is anything to save, if not, terminate */
let editedFields: string[] = Object.keys(editState);
if (!editedFields.length) {
@@ -233,8 +260,13 @@ const OrgEditor = ({
}
setEditData(baseData);
+ console.log(organization);
}, [existingEdit, organization]);
+ useEffect(() => {
+ console.log("change:", editData);
+ }, [editData]);
+
const saveChanges = async () => {
if (!savable) {
enqueueSnackbar(
@@ -299,9 +331,9 @@ const OrgEditor = ({
allNull = false; // even though all the fields could be null, this edit is worth keeping because the picture is different
} else if (
editPicture !==
- (existingEdit === undefined
- ? organization["picture"]
- : existingEdit["picture"]) &&
+ (existingEdit === undefined
+ ? organization["picture"]
+ : existingEdit["picture"]) &&
editPicture
) {
// picture is different, but needs to be uploaded first
@@ -392,10 +424,11 @@ const OrgEditor = ({
}
let data, error;
-
+ console.log(payload);
if (organization.state !== "PENDING") {
if (existingEdit.id === undefined) {
// insert new
+
({ data, error } = await supabase
.from("organizationedits")
.insert({ organization_id: organization.id, ...payload })
@@ -417,7 +450,6 @@ const OrgEditor = ({
delete payload[key];
}
}
-
({ data, error } = await supabase
.from("organizations")
.update(payload)
@@ -426,6 +458,7 @@ const OrgEditor = ({
}
if (error || !data) {
+ console.error(error);
return enqueueSnackbar(
"Error editing organization. Contact it@stuysu.org for support.",
{ variant: "error" },
@@ -497,6 +530,9 @@ const OrgEditor = ({
);
const updateEdit = (field: keyof OrganizationEdit, value: any) => {
+ if (field == "tags") {
+ setEditTags(value);
+ }
setEditData({
...editData,
[field]: value,
@@ -564,9 +600,9 @@ const OrgEditor = ({
if (
e.target.files[0].size >
1024 *
- 1024 *
- OrgRequirements.picture?.requirements
- ?.maxSize[0]
+ 1024 *
+ OrgRequirements.picture?.requirements
+ ?.maxSize[0]
) {
return enqueueSnackbar(
`File is too large. Max size is ${OrgRequirements.picture?.requirements?.maxSize[0]}MB.`,
@@ -621,7 +657,7 @@ const OrgEditor = ({
(existingEdit[field as keyof OrganizationEdit] !==
null &&
existingEdit[
- field as keyof OrganizationEdit
+ field as keyof OrganizationEdit
] !== undefined) ||
organization.state === "PENDING"
}
@@ -631,7 +667,7 @@ const OrgEditor = ({
updateEdit(
field as keyof OrganizationEdit,
existingEdit[field as keyof OrganizationEdit] ||
- organization[field as keyof Organization],
+ organization[field as keyof Organization],
);
// remove self from list of fields being edited
@@ -652,8 +688,8 @@ const OrgEditor = ({
setEditState({ ...editState, [field]: true })
}
defaultDisplay={
-
- {editData[field as keyof OrganizationEdit] || (
+
+ {formatStr(editData[field as keyof OrganizationEdit]) || (
<empty>
)}
@@ -670,7 +706,7 @@ const OrgEditor = ({
)
}
value={
- editData[field as keyof OrganizationEdit]
+ formatStr(editData[field as keyof OrganizationEdit])
}
required={OrgRequirements[field].required}
requirements={
@@ -684,6 +720,61 @@ const OrgEditor = ({
/>
);
})}
+
+ {
+ updateEdit(
+ "keywords" as keyof OrganizationEdit,
+ val.join(","),
+ )
+ }}
+ value={editData.keywords?.split(",") ?? []}
+ required={OrgRequirements.keywords.required}
+ requirements={OrgRequirements.keywords.requirements}
+ description={`You are allowed up to 3 keywords that describe your Activity. These will not be publicly visible but will help your Activity show up in search results. Examples of keywords include alternate names or acronyms, such as 'SU' for the Student Union. Create a keyword using or <,>. PLEASE NOTE: You cannot paste a list of keywords, you must type them manually.`}
+ />
+
+
+ updateEdit(
+ "tags" as keyof OrganizationEdit,
+ val,
+ )
+ }
+ />
+
+
{
);
};
-export default OrgAdminRouter;
+export default OrgAdminRouter;
\ No newline at end of file
From f86637baf1030b5b2e48fa2c7acc157ae0a76fe8 Mon Sep 17 00:00:00 2001
From: gdjolt8
Date: Thu, 25 Sep 2025 17:39:28 -0400
Subject: [PATCH 02/10] added keyword + tag edit
---
src/components/ui/buttons/LoginButton.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/ui/buttons/LoginButton.tsx b/src/components/ui/buttons/LoginButton.tsx
index 5de4cf58..c421358b 100644
--- a/src/components/ui/buttons/LoginButton.tsx
+++ b/src/components/ui/buttons/LoginButton.tsx
@@ -12,7 +12,7 @@ const LoginButton = ({ onMouseEnter, onMouseLeave }: LoginButtonProps) => {
const { error } = await supabase.auth.signInWithOAuth({
provider: "google",
options: {
- redirectTo: "http://localhost:3000",
+ redirectTo: PUBLIC_URL,
},
});
if (error) {
From 9913eea4f9d4a8c0735112ebcad7b5adb1013957 Mon Sep 17 00:00:00 2001
From: "Restyled.io"
Date: Thu, 25 Sep 2025 21:40:26 +0000
Subject: [PATCH 03/10] Restyled by whitespace
---
src/contexts/UserProvider.tsx | 2 +-
src/modules/stuyactivities/admin/index.tsx | 2 +-
src/modules/stuyactivities/admin/pages/ApprovePending.tsx | 2 +-
src/modules/stuyactivities/orgs/components/OrgNav.tsx | 2 +-
.../stuyactivities/orgs/org_admin/components/OrgEditor.tsx | 2 +-
src/modules/stuyactivities/orgs/org_admin/index.tsx | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/contexts/UserProvider.tsx b/src/contexts/UserProvider.tsx
index 30c88ce1..db737f86 100644
--- a/src/contexts/UserProvider.tsx
+++ b/src/contexts/UserProvider.tsx
@@ -201,4 +201,4 @@ const UserProvider = ({ children }: { children: React.ReactNode }) => {
);
};
-export default UserProvider;
\ No newline at end of file
+export default UserProvider;
diff --git a/src/modules/stuyactivities/admin/index.tsx b/src/modules/stuyactivities/admin/index.tsx
index 5b719539..abcfe70d 100644
--- a/src/modules/stuyactivities/admin/index.tsx
+++ b/src/modules/stuyactivities/admin/index.tsx
@@ -140,4 +140,4 @@ const AdminRouter = () => {
);
};
-export default AdminRouter;
\ No newline at end of file
+export default AdminRouter;
diff --git a/src/modules/stuyactivities/admin/pages/ApprovePending.tsx b/src/modules/stuyactivities/admin/pages/ApprovePending.tsx
index e7a7d889..fb229c41 100644
--- a/src/modules/stuyactivities/admin/pages/ApprovePending.tsx
+++ b/src/modules/stuyactivities/admin/pages/ApprovePending.tsx
@@ -60,7 +60,7 @@ const ApprovePending = () => {
const count = (await supabase.from("organizations").select('*').order('id', {ascending: true})).data;
console.log(count![0]);
-
+
if (error || !data) {
return enqueueSnackbar(
diff --git a/src/modules/stuyactivities/orgs/components/OrgNav.tsx b/src/modules/stuyactivities/orgs/components/OrgNav.tsx
index 488676e2..43fd19c0 100644
--- a/src/modules/stuyactivities/orgs/components/OrgNav.tsx
+++ b/src/modules/stuyactivities/orgs/components/OrgNav.tsx
@@ -177,4 +177,4 @@ const OrgNav = ({ isMobile }: { isMobile: boolean }) => {
);
};
-export default OrgNav;
\ No newline at end of file
+export default OrgNav;
diff --git a/src/modules/stuyactivities/orgs/org_admin/components/OrgEditor.tsx b/src/modules/stuyactivities/orgs/org_admin/components/OrgEditor.tsx
index a08e8576..e5aade59 100644
--- a/src/modules/stuyactivities/orgs/org_admin/components/OrgEditor.tsx
+++ b/src/modules/stuyactivities/orgs/org_admin/components/OrgEditor.tsx
@@ -741,7 +741,7 @@ const OrgEditor = ({
requirements={OrgRequirements.keywords.requirements}
description={`You are allowed up to 3 keywords that describe your Activity. These will not be publicly visible but will help your Activity show up in search results. Examples of keywords include alternate names or acronyms, such as 'SU' for the Student Union. Create a keyword using or <,>. PLEASE NOTE: You cannot paste a list of keywords, you must type them manually.`}
/>
-
+
{
);
};
-export default OrgAdminRouter;
\ No newline at end of file
+export default OrgAdminRouter;
From 487fe242d9ce38307a6e8e0f4ca8bfb0842d7803 Mon Sep 17 00:00:00 2001
From: gdjolt8
Date: Thu, 25 Sep 2025 17:45:14 -0400
Subject: [PATCH 04/10] added keyword + tag edit
---
src/components/ui/buttons/LoginButton.tsx | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/src/components/ui/buttons/LoginButton.tsx b/src/components/ui/buttons/LoginButton.tsx
index c421358b..32298949 100644
--- a/src/components/ui/buttons/LoginButton.tsx
+++ b/src/components/ui/buttons/LoginButton.tsx
@@ -23,19 +23,17 @@ const LoginButton = ({ onMouseEnter, onMouseLeave }: LoginButtonProps) => {
return (
-
- Sign in with Google
+ Sign in with Google
);
};
-export default LoginButton;
+export default LoginButton;
\ No newline at end of file
From de7f011f567be1ea7684f6f45362cf46579c5f96 Mon Sep 17 00:00:00 2001
From: "Restyled.io"
Date: Thu, 25 Sep 2025 22:02:02 +0000
Subject: [PATCH 05/10] Restyled by whitespace
---
src/components/ui/buttons/LoginButton.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/ui/buttons/LoginButton.tsx b/src/components/ui/buttons/LoginButton.tsx
index 32298949..e4618d48 100644
--- a/src/components/ui/buttons/LoginButton.tsx
+++ b/src/components/ui/buttons/LoginButton.tsx
@@ -36,4 +36,4 @@ const LoginButton = ({ onMouseEnter, onMouseLeave }: LoginButtonProps) => {
);
};
-export default LoginButton;
\ No newline at end of file
+export default LoginButton;
From 15de7b6605c0c28b60358fb065a6fa6945bb66dc Mon Sep 17 00:00:00 2001
From: gdjolt8
Date: Thu, 25 Sep 2025 20:05:08 -0400
Subject: [PATCH 06/10] other fixes
---
.../ui/forms/UnifiedChipSelector.tsx | 70 +++++++++++++++++++
.../admin/components/OrgApproval.tsx | 10 +--
.../orgs/org_admin/components/OrgEditor.tsx | 7 +-
3 files changed, 79 insertions(+), 8 deletions(-)
create mode 100644 src/components/ui/forms/UnifiedChipSelector.tsx
diff --git a/src/components/ui/forms/UnifiedChipSelector.tsx b/src/components/ui/forms/UnifiedChipSelector.tsx
new file mode 100644
index 00000000..f7a50773
--- /dev/null
+++ b/src/components/ui/forms/UnifiedChipSelector.tsx
@@ -0,0 +1,70 @@
+import React from 'react'
+import FormChipText from './FormChipText'
+import OrgRequirements from '../../../utils/OrgRequirements';
+import FormTagSelect from './FormTagSelect';
+import { SxProps } from '@mui/material';
+
+type Requirements = {
+ [field: string]: any;
+};
+
+type Props = {
+ field: string;
+ description?: string;
+ required?: boolean;
+ requirements?: Requirements;
+ value?: string | string[];
+ value_delim?: string;
+ onChange?: (updatedValue: string[]) => void;
+ status?: {
+ dirty: boolean;
+ value: boolean;
+ };
+ changeStatus?: (field: string, newStatus: boolean) => void;
+ label?: string;
+ options?: string[];
+ sx?: SxProps;
+};
+const UnifiedChipSelector = ({
+ field,
+ label,
+ onChange,
+ value,
+ changeStatus,
+ value_delim,
+ options,
+ description,
+ sx,
+}: Props) => {
+ if (typeof value === 'string') value = value.split(value_delim!);
+ const thereAreOptions = !!options;
+ if (!thereAreOptions) {
+ return (
+
+
+ )
+ } else {
+ return (
+
+ )
+ }
+}
+
+export default UnifiedChipSelector;
diff --git a/src/modules/stuyactivities/admin/components/OrgApproval.tsx b/src/modules/stuyactivities/admin/components/OrgApproval.tsx
index 774ece38..276c606a 100644
--- a/src/modules/stuyactivities/admin/components/OrgApproval.tsx
+++ b/src/modules/stuyactivities/admin/components/OrgApproval.tsx
@@ -8,6 +8,8 @@ import { useState } from "react";
import AsyncButton from "../../../../components/ui/buttons/AsyncButton";
import Divider from "../../../../components/ui/Divider";
+
+const acronyms = ["AI", "AP", "CS", "GSA"];
const OrgApproval = ({
onBack,
onDecision,
@@ -20,8 +22,6 @@ const OrgApproval = ({
const [buttonsDisabled, setButtonsDisabled] = useState(false);
const creator = org.memberships?.find((m) => m.role === 'CREATOR');
let keywords = org.keywords?.split(",");
- console.log(keywords);
- console.log(creator);
const approve = async () => {
setButtonsDisabled(true);
const { error } = await supabase.functions.invoke(
@@ -168,8 +168,8 @@ const OrgApproval = ({
Keywords
{!org.keywords && none
}
{org.keywords &&
- keywords?.map((n, _) => (
- {(["AI", "AP", "CS", "GSA"]).includes(n.toUpperCase()) ? n.toUpperCase() : n[0].toUpperCase() + n.slice(1)}
+ keywords?.map((n, i) => (
+ {acronyms.includes(n.toUpperCase()) ? n.toUpperCase() : n[0].toUpperCase() + n.slice(1)}
))
}
@@ -183,7 +183,7 @@ const OrgApproval = ({
Creator
- {creator?.users?.first_name} {" "} {creator?.users?.last_name}
+ {creator?.users?.first_name} {" "} {creator?.users?.last_name}
{creator?.users?.email}
diff --git a/src/modules/stuyactivities/orgs/org_admin/components/OrgEditor.tsx b/src/modules/stuyactivities/orgs/org_admin/components/OrgEditor.tsx
index e5aade59..2aca4a10 100644
--- a/src/modules/stuyactivities/orgs/org_admin/components/OrgEditor.tsx
+++ b/src/modules/stuyactivities/orgs/org_admin/components/OrgEditor.tsx
@@ -11,6 +11,7 @@ import AsyncButton from "../../../../../components/ui/buttons/AsyncButton";
import FormTagSelect from "../../../../../components/ui/forms/FormTagSelect";
import FormSection from "../../../../../components/ui/forms/FormSection";
import FormChipText from "../../../../../components/ui/forms/FormChipText";
+import UnifiedChipSelector from "../../../../../components/ui/forms/UnifiedChipSelector";
type Props = {
organization: Partial; // Make organization a prop to allow component to become reusable
@@ -727,7 +728,7 @@ const OrgEditor = ({
flexDirection: "column",
gap: "10px"
}}>
- {
@@ -742,10 +743,10 @@ const OrgEditor = ({
description={`You are allowed up to 3 keywords that describe your Activity. These will not be publicly visible but will help your Activity show up in search results. Examples of keywords include alternate names or acronyms, such as 'SU' for the Student Union. Create a keyword using or <,>. PLEASE NOTE: You cannot paste a list of keywords, you must type them manually.`}
/>
-
Date: Fri, 26 Sep 2025 00:05:44 +0000
Subject: [PATCH 07/10] Restyled by whitespace
---
src/components/ui/forms/UnifiedChipSelector.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/ui/forms/UnifiedChipSelector.tsx b/src/components/ui/forms/UnifiedChipSelector.tsx
index f7a50773..13987d47 100644
--- a/src/components/ui/forms/UnifiedChipSelector.tsx
+++ b/src/components/ui/forms/UnifiedChipSelector.tsx
@@ -53,7 +53,7 @@ const UnifiedChipSelector = ({
)
} else {
return (
-
Date: Thu, 25 Sep 2025 20:15:16 -0400
Subject: [PATCH 08/10] other fixes
---
src/components/ui/forms/FormTextField.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/components/ui/forms/FormTextField.tsx b/src/components/ui/forms/FormTextField.tsx
index f6057a0a..d34544bc 100644
--- a/src/components/ui/forms/FormTextField.tsx
+++ b/src/components/ui/forms/FormTextField.tsx
@@ -134,7 +134,7 @@ const FormTextField = ({
if (requirements.maxChar) {
if (countChars) {
- helperText += " to";
+ helperText += " to ";
} else {
helperText += ":";
}
@@ -143,7 +143,7 @@ const FormTextField = ({
helperText += `Maximum ${requirements.maxChar} Characters`;
}
- if (countChars) helperText += ` (${value?.length || 0}/${requirements.maxChar}.`;
+ if (countChars) helperText += ` (${value?.length || 0}/${requirements.maxChar}).`;
let countWords = false;
From ef83cb004079d9f8bc49636e31b85068b0554ffc Mon Sep 17 00:00:00 2001
From: gdjolt8
Date: Thu, 2 Oct 2025 16:17:22 -0400
Subject: [PATCH 09/10] URL descriptions
---
src/components/ui/forms/FormTextField.tsx | 36 +++++++++++++++-------
src/modules/stuyactivities/CharterForm.tsx | 21 ++++++++-----
2 files changed, 38 insertions(+), 19 deletions(-)
diff --git a/src/components/ui/forms/FormTextField.tsx b/src/components/ui/forms/FormTextField.tsx
index d34544bc..7159817f 100644
--- a/src/components/ui/forms/FormTextField.tsx
+++ b/src/components/ui/forms/FormTextField.tsx
@@ -24,6 +24,7 @@ type Props = {
};
changeStatus?: (field: string, newStatus: boolean) => void;
hideHelper?: boolean;
+ textHelper?: string;
};
const FormTextField = ({
@@ -36,6 +37,10 @@ const FormTextField = ({
status,
changeStatus,
hideHelper,
+ textHelper,
+ label,
+ sx,
+ error,
...textFieldProps
}: Props & TextFieldProps) => {
useEffect(() => {
@@ -80,7 +85,6 @@ const FormTextField = ({
const textChanged = (event: ChangeEvent) => {
let targetValue = event.target.value;
- console.log(`changed to ${targetValue}`, requirements!);
if (
requirements?.maxChar &&
targetValue.length > requirements.maxChar
@@ -90,7 +94,7 @@ const FormTextField = ({
if (
requirements?.maxWords &&
targetValue.replace(/ +/g, " ").split(" ").length >
- requirements.maxWords
+ requirements.maxWords
) {
targetValue = targetValue
.replace(/ +/g, " ")
@@ -132,9 +136,9 @@ const FormTextField = ({
helperText += `: Minimum ${requirements.minChar} Characters`;
}
- if (requirements.maxChar) {
+ if (requirements.maxChar && !description) {
if (countChars) {
- helperText += " to ";
+ helperText += " to";
} else {
helperText += ":";
}
@@ -143,7 +147,7 @@ const FormTextField = ({
helperText += `Maximum ${requirements.maxChar} Characters`;
}
- if (countChars) helperText += ` (${value?.length || 0}/${requirements.maxChar}).`;
+ if (countChars) helperText += ` (${value?.length || 0}/${requirements.maxChar}.`;
let countWords = false;
@@ -172,26 +176,36 @@ const FormTextField = ({
if (countWords)
helperText += ` (${value?.trim().split(" ").length || 0}/${requirements.maxWords})`;
}
-
return (
- {description?.split("\n").map((line) => (
- <>
+ {/* description */}
+ {description?.split("\n").map((line, idx) => (
+
{line}
- >
+
+ ))}
+
+ {/* internal helper text (requirements like min/max chars/words) */}
+ {textHelper?.split("\n").map((line, idx) => (
+
+ {line}
+
+
))}
- {helperText}
>
)
}
+ label={label}
+ sx={sx}
+
{...textFieldProps}
/>
);
diff --git a/src/modules/stuyactivities/CharterForm.tsx b/src/modules/stuyactivities/CharterForm.tsx
index a1720d87..6b51ea90 100644
--- a/src/modules/stuyactivities/CharterForm.tsx
+++ b/src/modules/stuyactivities/CharterForm.tsx
@@ -358,7 +358,7 @@ const CharterForm = () => {
sx={{ width: isMobile ? "100%" : "50%" }}
/>
\nExample: https://epsilon.stuysu.org/suit"
@@ -371,22 +371,26 @@ const CharterForm = () => {
width: isMobile ? "100%" : "50%",
}}
error={!!urlError}
- helperText={
- urlError
+ textHelper={
+ (`\nCurrently, the web page to access your Activity would be https://epsilon.stuysu.org/${formData.url}. \n`) +
+ (urlError
? urlError
: checkingUrl
- ? "Checking URL..."
- : formData.url && !urlError
- ? "URL is valid."
- : undefined
+ ? "Checking URL..."
+ : formData.url && !urlError
+ ? "URL is valid."
+ : "")
}
+
+
onBlur={async (e: any) => {
const url = e.target.value;
if (url) await validateUrl(url);
+ if (url.length < 1) setUrlError("");
}}
onChange={(e: any) => {
const url = e.target.value;
- if (url === "" || urlPattern.test(url)) {
+ if (url.length < 1 || urlPattern.test(url)) {
setFormData((prev) => ({ ...prev, url }));
setUrlError("");
} else {
@@ -396,6 +400,7 @@ const CharterForm = () => {
}
}}
inputProps={{ pattern: urlPattern.source }}
+ hideHelper={false}
/>
Date: Thu, 2 Oct 2025 16:18:25 -0400
Subject: [PATCH 10/10] URL descriptions
---
src/components/ui/forms/FormTextField.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/components/ui/forms/FormTextField.tsx b/src/components/ui/forms/FormTextField.tsx
index 7159817f..20aca79f 100644
--- a/src/components/ui/forms/FormTextField.tsx
+++ b/src/components/ui/forms/FormTextField.tsx
@@ -138,7 +138,7 @@ const FormTextField = ({
if (requirements.maxChar && !description) {
if (countChars) {
- helperText += " to";
+ helperText += " to ";
} else {
helperText += ":";
}
@@ -147,7 +147,7 @@ const FormTextField = ({
helperText += `Maximum ${requirements.maxChar} Characters`;
}
- if (countChars) helperText += ` (${value?.length || 0}/${requirements.maxChar}.`;
+ if (countChars) helperText += ` (${value?.length || 0}/${requirements.maxChar}).`;
let countWords = false;