diff --git a/admin/src/components/Achievements.tsx b/admin/src/components/Achievements.tsx
index f60ee56e..f6dab953 100644
--- a/admin/src/components/Achievements.tsx
+++ b/admin/src/components/Achievements.tsx
@@ -52,6 +52,7 @@ function AchiemementCard(props: {
onSelect: () => void;
onEdit: () => void;
onDelete: () => void;
+ onCopy: () => void;
}) {
return (
<>
@@ -80,6 +81,9 @@ function AchiemementCard(props: {
EDIT
+
+ COPY
+
>
@@ -146,6 +150,16 @@ function toForm(achievement: AchievementDto) {
] as EntryForm[];
}
+function makeCopyForm(orgOptions: string[], initialIndex: number) {
+ return [
+ {
+ name: "Target Organization",
+ options: orgOptions,
+ value: initialIndex,
+ },
+ ] as EntryForm[];
+}
+
export function Achievements() {
const serverData = useContext(ServerDataContext);
const [isCreateModalOpen, setCreateModalOpen] = useState(false);
@@ -153,6 +167,13 @@ export function Achievements() {
const [isDeleteModalOpen, setDeleteModalOpen] = useState(false);
const [selectModalOpen, setSelectModalOpen] = useState(false);
const [isLinkedModalOpen, setLinkedModalOpen] = useState(false);
+
+ const [isCopyModalOpen, setCopyModalOpen] = useState(false);
+ const [copyForm, setCopyForm] = useState(() => ({
+ form: makeCopyForm([], 0),
+ orgIds: [] as string[],
+ }));
+
const [form, setForm] = useState(() => makeForm());
const [currentId, setCurrentId] = useState("");
const [query, setQuery] = useState("");
@@ -203,6 +224,26 @@ export function Achievements() {
}}
form={form}
/>
+ {
+ const ach = serverData.achievements.get(currentId)!;
+ serverData.updateAchievement({
+ ...ach,
+ eventId: "",
+ initialOrganizationId:
+ copyForm.orgIds[(copyForm.form[0] as OptionEntryForm).value],
+ id: "",
+ });
+ setCopyModalOpen(false);
+ }}
+ onCancel={() => {
+ setCopyModalOpen(false);
+ }}
+ form={copyForm.form}
+ />
{
+ const orgs = Array.from(serverData.organizations.values());
+ const myOrgIndex = orgs.findIndex(
+ (v) => v.id === selectedOrg?.id
+ );
+ setCurrentId(ach.id);
+ setCopyForm({
+ form: makeCopyForm(
+ orgs.map((org) => org.name ?? ""),
+ myOrgIndex
+ ),
+ orgIds: orgs.map((org) => org.id),
+ });
+ setCopyModalOpen(true);
+ }}
/>
))}
>
diff --git a/admin/src/components/Challenges.tsx b/admin/src/components/Challenges.tsx
index a70da10d..d772fc5e 100644
--- a/admin/src/components/Challenges.tsx
+++ b/admin/src/components/Challenges.tsx
@@ -54,6 +54,7 @@ function ChallengeCard(props: {
onDown: () => void;
onDelete: () => void;
onEdit: () => void;
+ onCopy: () => void;
}) {
return (
@@ -79,6 +80,9 @@ function ChallengeCard(props: {
EDIT
+
+ COPY
+
);
@@ -170,6 +174,16 @@ function fromForm(
};
}
+function makeCopyForm(evOptions: string[], initialIndex: number) {
+ return [
+ {
+ name: "Target Event",
+ options: evOptions,
+ value: initialIndex,
+ },
+ ] as EntryForm[];
+}
+
export function Challenges() {
const [createModalOpen, setCreateModalOpen] = useState(false);
const [editModalOpen, setEditModalOpen] = useState(false);
@@ -180,6 +194,12 @@ export function Challenges() {
const [currentId, setCurrentId] = useState("");
const [query, setQuery] = useState("");
+ const [isCopyModalOpen, setCopyModalOpen] = useState(false);
+ const [copyForm, setCopyForm] = useState(() => ({
+ form: makeCopyForm([], 0),
+ evIds: [] as string[],
+ }));
+
const serverData = useContext(ServerDataContext);
const selectedEvent = serverData.events.get(serverData.selectedEvent);
@@ -229,6 +249,25 @@ export function Challenges() {
setDeleteModalOpen(false);
}}
/>
+ {
+ const chal = serverData.challenges.get(currentId)!;
+ serverData.updateChallenge({
+ ...chal,
+ linkedEventId:
+ copyForm.evIds[(copyForm.form[0] as OptionEntryForm).value],
+ id: "",
+ });
+ setCopyModalOpen(false);
+ }}
+ onCancel={() => {
+ setCopyModalOpen(false);
+ }}
+ form={copyForm.form}
+ />
{
setForm(makeForm());
@@ -292,6 +331,21 @@ export function Challenges() {
setCurrentId(chal.id);
setDeleteModalOpen(true);
}}
+ onCopy={() => {
+ const evs = Array.from(serverData.events.values());
+ const myEvIndex = evs.findIndex(
+ (v) => v.id === selectedEvent?.id
+ );
+ setCurrentId(chal.id);
+ setCopyForm({
+ form: makeCopyForm(
+ evs.map((ev) => ev.name ?? ""),
+ myEvIndex
+ ),
+ evIds: evs.map((ev) => ev.id),
+ });
+ setCopyModalOpen(true);
+ }}
/>
))}
>
diff --git a/admin/src/components/Events.tsx b/admin/src/components/Events.tsx
index 0572c930..5371d240 100644
--- a/admin/src/components/Events.tsx
+++ b/admin/src/components/Events.tsx
@@ -221,12 +221,14 @@ export function Events() {
const [isEditModalOpen, setEditModalOpen] = useState(false);
const [isDeleteModalOpen, setDeleteModalOpen] = useState(false);
const [selectModalOpen, setSelectModalOpen] = useState(false);
+
const [isCopyModalOpen, setCopyModalOpen] = useState(false);
- const [form, setForm] = useState(() => makeForm());
const [copyForm, setCopyForm] = useState(() => ({
form: makeCopyForm([], 0),
orgIds: [] as string[],
}));
+
+ const [form, setForm] = useState(() => makeForm());
const [currentId, setCurrentId] = useState("");
const [query, setQuery] = useState("");
const selectedOrg = serverData.organizations.get(serverData.selectedOrg);