Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { useEffect, useState } from "react";
import { useDispatch } from "react-redux";
import AppendantEditor from "./editor";
import AppendantPopupLayout from "./popupLayout";
import { CreateButton } from "./submitButton";
import {
newErrorToast,
newSuccessToast,
} from "next-common/store/reducers/toastSlice";

export default function AppendantFormPopup({
title,
description = "",
onClose,
onSuccess,
submit,
successMessage,
initialContent = "",
initialContentType = "markdown",
SubmitButton = CreateButton,
}) {
const [content, setContent] = useState(initialContent || "");
const [contentType, setContentType] = useState(
initialContentType || "markdown",
);
const [errors, setErrors] = useState();
const [submitting, setSubmitting] = useState(false);
const dispatch = useDispatch();

useEffect(() => {
setContent(initialContent || "");
setContentType(initialContentType || "markdown");
}, [initialContent, initialContentType]);

const handleSubmit = async () => {
setSubmitting(true);
setErrors(null);

try {
const { result, error } = await submit(content, contentType);
if (error) {
if (error.data) {
setErrors(error);
} else {
dispatch(newErrorToast(error.message));
}
return;
}

if (result) {
dispatch(newSuccessToast(successMessage));
onSuccess?.();
onClose();
}
} catch (e) {
if (e.message !== "Cancelled") {
dispatch(newErrorToast(e.message));
}
} finally {
setSubmitting(false);
}
};

return (
<AppendantPopupLayout
title={title}
description={description}
onClose={onClose}
loading={submitting}
actions={
<SubmitButton
onClick={handleSubmit}
loading={submitting}
content={content}
/>
}
>
<AppendantEditor
value={content}
onChange={setContent}
contentType={contentType}
onContentTypeChange={setContentType}
errors={errors}
disabled={submitting}
/>
</AppendantPopupLayout>
);
}
77 changes: 14 additions & 63 deletions packages/next-common/components/appendants/common/createPopup.jsx
Original file line number Diff line number Diff line change
@@ -1,83 +1,34 @@
import { useState } from "react";
import { useDispatch } from "react-redux";
import { useEnsureLogin } from "next-common/hooks/useEnsureLogin";
import {
newErrorToast,
newSuccessToast,
} from "next-common/store/reducers/toastSlice";
import nextApi from "next-common/services/nextApi";
import AppendantEditor from "./editor";
import AppendantPopupLayout from "./popupLayout";
import { CreateButton } from "./submitButton";
import AppendantFormPopup from "./appendantFormPopup";

export default function CreateAppendantPopup({
onClose,
createApi,
onSuccess,
description = "",
}) {
const [content, setContent] = useState("");
const [contentType, setContentType] = useState("markdown");
const [errors, setErrors] = useState();
const [submitting, setSubmitting] = useState(false);
const dispatch = useDispatch();
const { ensureLogin } = useEnsureLogin();

const handleSubmit = async () => {
setSubmitting(true);
setErrors(null);

try {
if (!(await ensureLogin())) {
return;
}

const { result, error } = await nextApi.post(createApi, {
content,
contentType,
});

if (error) {
if (error.data) {
setErrors(error);
} else {
dispatch(newErrorToast(error.message));
}
return;
}

if (result) {
dispatch(newSuccessToast("Appendant created successfully"));
onSuccess?.();
onClose();
}
} finally {
setSubmitting(false);
const submit = async (content, contentType) => {
if (!(await ensureLogin())) {
throw new Error("Cancelled");
}

return await nextApi.post(createApi, {
content,
contentType,
});
};

return (
<AppendantPopupLayout
<AppendantFormPopup
title="Create Appendant"
description={description}
onClose={onClose}
loading={submitting}
actions={
<CreateButton
onClick={handleSubmit}
loading={submitting}
content={content}
/>
}
>
<AppendantEditor
value={content}
onChange={setContent}
contentType={contentType}
onContentTypeChange={setContentType}
errors={errors}
disabled={submitting}
/>
</AppendantPopupLayout>
onSuccess={onSuccess}
submit={submit}
successMessage="Appendant created successfully"
/>
);
}
86 changes: 17 additions & 69 deletions packages/next-common/components/appendants/common/editPopup.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
import { useState, useEffect } from "react";
import { useDispatch } from "react-redux";
import { useEnsureLogin } from "next-common/hooks/useEnsureLogin";
import {
newErrorToast,
newSuccessToast,
} from "next-common/store/reducers/toastSlice";
import { appendantsApi } from "next-common/services/url";
import nextApi from "next-common/services/nextApi";
import AppendantEditor from "./editor";
import AppendantPopupLayout from "./popupLayout";
import AppendantFormPopup from "./appendantFormPopup";
import { UpdateButton } from "./submitButton";

export default function EditAppendantPopup({
Expand All @@ -17,76 +10,31 @@ export default function EditAppendantPopup({
onSuccess,
description = "You are editing an appendant.",
}) {
const [content, setContent] = useState("");
const [contentType, setContentType] = useState("markdown");
const [errors, setErrors] = useState();
const [submitting, setSubmitting] = useState(false);
const dispatch = useDispatch();
const { ensureLogin } = useEnsureLogin();

useEffect(() => {
if (editData) {
setContent(editData.content || "");
setContentType(editData.contentType || "markdown");
const submit = async (content, contentType) => {
if (!(await ensureLogin())) {
throw new Error("Cancelled");
}
}, [editData]);

const handleSubmit = async () => {
setSubmitting(true);
setErrors(null);

try {
if (!(await ensureLogin())) {
return;
}

const updateApi = appendantsApi(editData?._id);
const { result, error } = await nextApi.patch(updateApi, {
content,
contentType,
});

if (error) {
if (error.data) {
setErrors(error);
} else {
dispatch(newErrorToast(error.message));
}
return;
}

if (result) {
dispatch(newSuccessToast("Appendant updated successfully"));
onSuccess?.();
onClose();
}
} finally {
setSubmitting(false);
}
const updateApi = appendantsApi(editData?._id);
return await nextApi.patch(updateApi, {
content,
contentType,
});
};

return (
<AppendantPopupLayout
<AppendantFormPopup
title="Edit Appendant"
description={description}
onClose={onClose}
loading={submitting}
actions={
<UpdateButton
onClick={handleSubmit}
loading={submitting}
content={content}
/>
}
>
<AppendantEditor
value={content}
onChange={setContent}
contentType={contentType}
onContentTypeChange={setContentType}
errors={errors}
disabled={submitting}
/>
</AppendantPopupLayout>
onSuccess={onSuccess}
submit={submit}
successMessage="Appendant updated successfully"
initialContent={editData?.content || ""}
initialContentType={editData?.contentType || "markdown"}
SubmitButton={UpdateButton}
/>
);
}
21 changes: 21 additions & 0 deletions packages/next-common/components/appendants/common/item.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { formatTimeAgo } from "next-common/utils/viewfuncs/formatTimeAgo";
import Tooltip from "next-common/components/tooltip";
import useIsAppendantAuthor from "../useIsAppendantAuthor";
import correctionIpfsEndpointPlugin from "next-common/utils/previewerPlugins/correctionIpfsEndpoint";
import AppendantEditedMarker from "next-common/sima/components/appendantEditedMarker";

function SplitDot() {
return <span className="text-textTertiary text12Medium mx-2">·</span>;
Expand Down Expand Up @@ -56,6 +57,21 @@ function Header({ index, data }) {
);
}

function getTimeValue(value) {
if (!value) {
return null;
}
const time =
value instanceof Date ? value.getTime() : new Date(value).getTime();
return Number.isNaN(time) ? null : time;
}

function isAppendantEdited(data) {
const createdAt = getTimeValue(data?.createdAt);
const updatedAt = getTimeValue(data?.updatedAt);
return createdAt !== null && updatedAt !== null && updatedAt !== createdAt;
}

function Content({ data }) {
return (
<div>
Expand Down Expand Up @@ -100,6 +116,11 @@ export default function AppendantItem({ index, data, MoreActions }) {
{isAuthor && MoreActions && <MoreActions data={data} />}
</div>
<Content data={data} />
{isAppendantEdited(data) &&
data?.dataSource === "sima" &&
data?.cid && (
<AppendantEditedMarker appendant={data} className="mt-2" />
)}
</div>
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import { gov2ReferendaAppendantApi } from "next-common/services/url";
import { useReferendaAppendantsContext } from "next-common/context/referendaAppendants";
import { usePageProps } from "next-common/context/page";
import CreateAppendantPopup from "../common/createPopup";
import { usePost } from "next-common/context/post";
import { useArticleActions } from "next-common/sima/context/articleActions";
import LegacyCreateAppendantPopup from "./legacyCreatePopup";
import SimaCreateAppendantPopup from "./simaCreatePopup";

export default function ReferendaCreateAppendantPopup({ setIsAppend }) {
const { update } = useReferendaAppendantsContext();
const { id } = usePageProps();
const createApi = gov2ReferendaAppendantApi(id);
const post = usePost();
const { supportSima } = useArticleActions();

return (
<CreateAppendantPopup
onClose={() => setIsAppend(false)}
createApi={createApi}
onSuccess={update}
description="You are adding an appendant as authors."
/>
);
const isSimaPost =
supportSima && post?.refToPost?.postType === "referendaReferendum";

if (isSimaPost) {
return <SimaCreateAppendantPopup setIsAppend={setIsAppend} />;
}

return <LegacyCreateAppendantPopup setIsAppend={setIsAppend} />;
}
Loading
Loading