) => {
const { enqueueSnackbar } = useSnackbar();
const [buttonsDisabled, setButtonsDisabled] = useState(false);
-
+ const creator = org.memberships?.find((m) => m.role === 'CREATOR');
+ let keywords = org.keywords?.split(",");
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, i) => (
+ {acronyms.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/pages/ApprovePending.tsx b/src/modules/stuyactivities/admin/pages/ApprovePending.tsx
index 94986c3b..fb229c41 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/org_admin/components/OrgEditor.tsx b/src/modules/stuyactivities/orgs/org_admin/components/OrgEditor.tsx
index 7dac43b4..2aca4a10 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,10 @@ 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";
+import UnifiedChipSelector from "../../../../../components/ui/forms/UnifiedChipSelector";
type Props = {
organization: Partial; // Make organization a prop to allow component to become reusable
@@ -28,6 +32,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 +137,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 +163,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 +177,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 +199,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 +261,13 @@ const OrgEditor = ({
}
setEditData(baseData);
+ console.log(organization);
}, [existingEdit, organization]);
+ useEffect(() => {
+ console.log("change:", editData);
+ }, [editData]);
+
const saveChanges = async () => {
if (!savable) {
enqueueSnackbar(
@@ -299,9 +332,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 +425,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 +451,6 @@ const OrgEditor = ({
delete payload[key];
}
}
-
({ data, error } = await supabase
.from("organizations")
.update(payload)
@@ -426,6 +459,7 @@ const OrgEditor = ({
}
if (error || !data) {
+ console.error(error);
return enqueueSnackbar(
"Error editing organization. Contact it@stuysu.org for support.",
{ variant: "error" },
@@ -497,6 +531,9 @@ const OrgEditor = ({
);
const updateEdit = (field: keyof OrganizationEdit, value: any) => {
+ if (field == "tags") {
+ setEditTags(value);
+ }
setEditData({
...editData,
[field]: value,
@@ -564,9 +601,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 +658,7 @@ const OrgEditor = ({
(existingEdit[field as keyof OrganizationEdit] !==
null &&
existingEdit[
- field as keyof OrganizationEdit
+ field as keyof OrganizationEdit
] !== undefined) ||
organization.state === "PENDING"
}
@@ -631,7 +668,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 +689,8 @@ const OrgEditor = ({
setEditState({ ...editState, [field]: true })
}
defaultDisplay={
-
- {editData[field as keyof OrganizationEdit] || (
+
+ {formatStr(editData[field as keyof OrganizationEdit]) || (
<empty>
)}
@@ -670,7 +707,7 @@ const OrgEditor = ({
)
}
value={
- editData[field as keyof OrganizationEdit]
+ formatStr(editData[field as keyof OrganizationEdit])
}
required={OrgRequirements[field].required}
requirements={
@@ -684,6 +721,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,
+ )
+ }
+ />
+
+