From 639289eff396f4d49b2e4f02ad984200e59461f9 Mon Sep 17 00:00:00 2001 From: Sanjay Prajapati Date: Sat, 20 Nov 2021 14:47:27 -0600 Subject: [PATCH 1/7] MH-249: initial commit --- apps/moderation/api/urls.py | 9 ++ apps/moderation/api/views.py | 14 +++ core/urls.py | 1 + frontend/components/Navbar.tsx | 8 ++ .../users/[handle]/contributions.page.tsx | 93 +++++++++++++++++++ 5 files changed, 125 insertions(+) create mode 100644 apps/moderation/api/urls.py create mode 100644 frontend/pages/users/[handle]/contributions.page.tsx diff --git a/apps/moderation/api/urls.py b/apps/moderation/api/urls.py new file mode 100644 index 000000000..32ebcb19a --- /dev/null +++ b/apps/moderation/api/urls.py @@ -0,0 +1,9 @@ +from django.urls import path + +from apps.moderation.api import views + +app_name = 'moderation' + +urlpatterns = [ + path('contributions/', views.ContentContributionAPIView.as_view()), +] diff --git a/apps/moderation/api/views.py b/apps/moderation/api/views.py index e69de29bb..791fbdbd6 100644 --- a/apps/moderation/api/views.py +++ b/apps/moderation/api/views.py @@ -0,0 +1,14 @@ +from rest_framework.response import Response +from rest_framework.views import APIView + +from apps.moderation.models import ContentContribution + + +class ContentContributionAPIView(APIView): + """API endpoint for content contribution.""" + + def get(self, request): + """Return the contents contributed""" + results = ContentContribution.objects.filter(contributor=request.user) + + return Response([result.serialize() for result in results]) diff --git a/core/urls.py b/core/urls.py index 111e79686..5b19d4684 100644 --- a/core/urls.py +++ b/core/urls.py @@ -73,6 +73,7 @@ def error(request: 'HttpRequest'): path('api/forums/', include(_api('forums'), namespace='forums_api')), path('api/home/', include(_api('home'), namespace='home_api')), path('api/images/', include(_api('images'), namespace='images_api')), + path('api/moderation/', include(_api('moderation'), namespace='moderation_api')), path('api/occurrences/', include(_api('occurrences'), namespace='occurrences_api')), path('api/places/', include(_api('places'), namespace='places_api')), path('api/propositions/', include(_api('propositions'), namespace='propositions_api')), diff --git a/frontend/components/Navbar.tsx b/frontend/components/Navbar.tsx index 80fcc55ed..b110ada8e 100644 --- a/frontend/components/Navbar.tsx +++ b/frontend/components/Navbar.tsx @@ -133,6 +133,14 @@ const GlobalNavbar: FC = ({ menuItems }: GlobalNavbarProps) = Settings + { + <> + + + My Contributions + + + } {(session.user.isSuperuser && ( <> diff --git a/frontend/pages/users/[handle]/contributions.page.tsx b/frontend/pages/users/[handle]/contributions.page.tsx new file mode 100644 index 000000000..f399bc313 --- /dev/null +++ b/frontend/pages/users/[handle]/contributions.page.tsx @@ -0,0 +1,93 @@ +import axiosWithoutAuth from "@/axiosWithoutAuth"; +import Layout from "@/components/Layout"; +import { Container } from "@mui/material"; +import Grid from "@mui/material/Grid"; +import Paper from "@mui/material/Paper"; +import Typography from "@mui/material/Typography"; +import { GetServerSideProps } from "next"; +import { User } from "next-auth"; +import { getSession, useSession } from "next-auth/client"; +import React, { FC } from "react"; +import Image from "react-bootstrap/Image"; + +interface UserContributionsPageProps { + user?: User; + usercontributions: any; +} + +const UserContributionsPage: FC = ({ + user, + usercontributions, +}: UserContributionsPageProps) => { + const [session, _loading] = useSession(); + if (!user || _loading) return null; + if (session) { + return ( + + + + +
+ {`profile +
+
+ + + + {" "} + My Contributions{" "} + + + +
+
+
+ ); + } else { + return null; + } +}; +export default UserContributionsPage; + +// https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering +export const getServerSideProps: GetServerSideProps = async (context) => { + const session = await getSession(context); + let usercontributions = null; + if (!session?.user) { + return { + redirect: { + destination: "/", + permanent: false, + }, + }; + } + await axiosWithoutAuth + .get("http://django:8000/api/moderation/contributions/") + .then((response) => { + usercontributions = response.data; + }) + .catch((error) => { + console.error(error); + }); + return { + props: { + usercontributions, + user: session?.user ?? null, + }, + }; +}; From 9a62c057ef4f78d43a4113d9a03388cbdaa2f5b6 Mon Sep 17 00:00:00 2001 From: Sanjay Prajapati Date: Tue, 23 Nov 2021 12:09:35 -0600 Subject: [PATCH 2/7] refactoring --- .../users/[handle]/contributions.page.tsx | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/frontend/pages/users/[handle]/contributions.page.tsx b/frontend/pages/users/[handle]/contributions.page.tsx index f399bc313..9b93de88c 100644 --- a/frontend/pages/users/[handle]/contributions.page.tsx +++ b/frontend/pages/users/[handle]/contributions.page.tsx @@ -1,18 +1,20 @@ import axiosWithoutAuth from "@/axiosWithoutAuth"; +import ModuleUnionCard from "@/components/cards/ModuleUnionCard"; import Layout from "@/components/Layout"; -import { Container } from "@mui/material"; +import { Card, CardContent, CardHeader, Container, Skeleton } from "@mui/material"; import Grid from "@mui/material/Grid"; import Paper from "@mui/material/Paper"; import Typography from "@mui/material/Typography"; import { GetServerSideProps } from "next"; import { User } from "next-auth"; import { getSession, useSession } from "next-auth/client"; +import Link from "next/link"; import React, { FC } from "react"; import Image from "react-bootstrap/Image"; interface UserContributionsPageProps { user?: User; - usercontributions: any; + usercontributions: any[]; } const UserContributionsPage: FC = ({ @@ -52,6 +54,33 @@ const UserContributionsPage: FC = ({ {" "} My Contributions{" "} + <> + {usercontributions.length ? ( + usercontributions.map((module, index) => ( + + + + + + + + )) + ) : _loading ? ( + + + + + ) : ( +

+ Sorry! There are no content contributions made. If you`'`d like to + contribute, please visit (link). +

+ )} + @@ -67,7 +96,7 @@ export default UserContributionsPage; // https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering export const getServerSideProps: GetServerSideProps = async (context) => { const session = await getSession(context); - let usercontributions = null; + let usercontributions: UserContributionsPageProps[] = []; if (!session?.user) { return { redirect: { From 42b3a7dfb037fda032f0827bd7a9ea7e69d885c7 Mon Sep 17 00:00:00 2001 From: Sanjay Prajapati Date: Fri, 3 Dec 2021 23:25:02 -0600 Subject: [PATCH 3/7] refactoring --- apps/moderation/api/serializers.py | 12 ++++++++++++ apps/moderation/api/views.py | 5 +++-- apps/moderation/fields.py | 9 ++++++++- apps/moderation/models/contribution.py | 8 ++++++++ 4 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 apps/moderation/api/serializers.py diff --git a/apps/moderation/api/serializers.py b/apps/moderation/api/serializers.py new file mode 100644 index 000000000..00be50bcf --- /dev/null +++ b/apps/moderation/api/serializers.py @@ -0,0 +1,12 @@ +from rest_framework import serializers +from rest_framework.serializers import ModelSerializer + +from apps.moderation.models.contribution import ContentContribution + + +class ContentContributionSerializer(serializers.ModelSerializer): + """Serializer for ContentContribution.""" + + class Meta: + model = ContentContribution + fields = '__all__' diff --git a/apps/moderation/api/views.py b/apps/moderation/api/views.py index 791fbdbd6..8744b1972 100644 --- a/apps/moderation/api/views.py +++ b/apps/moderation/api/views.py @@ -1,7 +1,8 @@ from rest_framework.response import Response from rest_framework.views import APIView -from apps.moderation.models import ContentContribution +from apps.moderation.api.serializers import ContentContributionSerializer +from apps.moderation.models.contribution import ContentContribution class ContentContributionAPIView(APIView): @@ -11,4 +12,4 @@ def get(self, request): """Return the contents contributed""" results = ContentContribution.objects.filter(contributor=request.user) - return Response([result.serialize() for result in results]) + return Response([ContentContributionSerializer(result).data for result in results]) diff --git a/apps/moderation/fields.py b/apps/moderation/fields.py index f65c7d61e..8acd3d6df 100644 --- a/apps/moderation/fields.py +++ b/apps/moderation/fields.py @@ -11,12 +11,19 @@ SerializedModel = list[dict] +class SerializerJSONEncoder(JSONEncoder): + def default(self, obj): + if hasattr(obj, 'serialize'): + return obj.serialize() + return super().default(obj) + + class SerializedObjectField(JSONField): """Model field for storing a serialized model instance.""" def __init__(self, *args, **kwargs): """Construct the field.""" - kwargs['encoder'] = JSONEncoder + kwargs['encoder'] = SerializerJSONEncoder kwargs['editable'] = False super().__init__(*args, **kwargs) diff --git a/apps/moderation/models/contribution.py b/apps/moderation/models/contribution.py index afc10e0ab..ce7c78411 100644 --- a/apps/moderation/models/contribution.py +++ b/apps/moderation/models/contribution.py @@ -28,3 +28,11 @@ class ContentContribution(models.Model): def __str__(self) -> str: return f'Contribution by {self.contributor} to {self.change} ({self.date_created})' + + +@classmethod +def get_serializer(self): + """Return the serializer for ContentContribution""" + from apps.moderation.api.serializers import ContentContributionSerializer + + return ContentContributionSerializer From 44454c4ff02b2bd1ed072ed9490e0abe37dbbf6f Mon Sep 17 00:00:00 2001 From: Jacob Fredericksen Date: Wed, 8 Dec 2021 17:01:05 -0600 Subject: [PATCH 4/7] Merge branch 'main' into MH-249 From 16e76517aa22e9538d75e1cfa0aac4584732a61a Mon Sep 17 00:00:00 2001 From: Jacob Fredericksen Date: Wed, 8 Dec 2021 18:30:28 -0600 Subject: [PATCH 5/7] refactoring --- apps/flatpages/models.py | 7 +++ apps/moderation/api/serializers.py | 21 +++++++-- apps/moderation/api/views.py | 19 ++++++-- apps/moderation/models/contribution.py | 8 +++- core/models/model.py | 27 ++++++----- core/models/module.py | 4 -- frontend/components/Navbar.tsx | 12 ++--- frontend/components/TodayInHistory.tsx | 2 +- .../__tests__/TodayInHistory.test.tsx | 2 +- frontend/components/cards/ModuleCard.tsx | 2 +- frontend/components/cards/ModuleUnionCard.tsx | 2 +- frontend/components/details/ModuleDetail.tsx | 2 +- frontend/components/details/ModuleLink.tsx | 2 +- frontend/components/details/ModuleModal.tsx | 2 +- frontend/components/entities/EntityDetail.tsx | 2 +- frontend/components/images/ImageCard.tsx | 2 +- frontend/components/images/ImageDetail.tsx | 2 +- .../components/propositions/ArgumentSet.tsx | 2 +- .../propositions/InlineProposition.tsx | 2 +- .../propositions/OccurrenceDetail.tsx | 2 +- .../propositions/PropositionDetail.tsx | 2 +- frontend/components/quotes/QuoteDetail.tsx | 2 +- frontend/components/search/Timeline.tsx | 2 +- frontend/components/sources/SourceDetail.tsx | 2 +- frontend/components/topics/Tag.tsx | 2 +- frontend/components/topics/TagList.tsx | 2 +- frontend/components/topics/TopicDetail.tsx | 2 +- frontend/pages/[...path].page.tsx | 2 +- frontend/pages/__tests__/search.test.tsx | 2 +- frontend/pages/collections/[slug].page.tsx | 2 +- frontend/pages/collections/index.page.tsx | 2 +- frontend/pages/entities/[slug].page.tsx | 2 +- frontend/pages/entities/index.page.tsx | 2 +- frontend/pages/images/[slug].page.tsx | 2 +- frontend/pages/images/index.page.tsx | 2 +- frontend/pages/index.page.tsx | 2 +- frontend/pages/occurrences/[slug].page.tsx | 2 +- frontend/pages/occurrences/index.page.tsx | 2 +- frontend/pages/propositions/[slug].page.tsx | 2 +- frontend/pages/propositions/index.page.tsx | 2 +- frontend/pages/quotes/[slug].page.tsx | 2 +- frontend/pages/quotes/index.page.tsx | 2 +- frontend/pages/search.page.tsx | 2 +- frontend/pages/sources/[slug].page.tsx | 2 +- frontend/pages/sources/index.page.tsx | 2 +- frontend/pages/topics/[slug].page.tsx | 2 +- frontend/pages/topics/index.page.tsx | 2 +- .../users/[handle]/contributions.page.tsx | 46 ++++++++++++------- frontend/types/{modules.d.ts => models.d.ts} | 7 +++ 49 files changed, 143 insertions(+), 88 deletions(-) rename frontend/types/{modules.d.ts => models.d.ts} (96%) diff --git a/apps/flatpages/models.py b/apps/flatpages/models.py index 910c43ab2..c71d725c2 100644 --- a/apps/flatpages/models.py +++ b/apps/flatpages/models.py @@ -60,6 +60,13 @@ class Meta: class Moderation(ModeratedModel.Moderation): excluded_fields = ModeratedModel.Moderation.excluded_fields + ['sites'] + @classmethod + def get_serializer(self): + """Return the serializer for the entity.""" + from apps.flatpages.api.serializers import FlatPageSerializer + + return FlatPageSerializer + def __str__(self) -> str: return f'{self.path} -- {self.title}' diff --git a/apps/moderation/api/serializers.py b/apps/moderation/api/serializers.py index 00be50bcf..5a45cfd51 100644 --- a/apps/moderation/api/serializers.py +++ b/apps/moderation/api/serializers.py @@ -1,12 +1,27 @@ from rest_framework import serializers -from rest_framework.serializers import ModelSerializer -from apps.moderation.models.contribution import ContentContribution +from apps.moderation.models import Change, ContentContribution + + +class ChangeSerializer(serializers.ModelSerializer): + + content_object = serializers.SerializerMethodField() + + class Meta: + model = Change + fields = ('content_object',) + + def get_content_object(self, obj: Change): + return obj.content_object.serialize() class ContentContributionSerializer(serializers.ModelSerializer): """Serializer for ContentContribution.""" + absolute_url = serializers.CharField(required=False, read_only=True) + change = ChangeSerializer(read_only=True) + class Meta: model = ContentContribution - fields = '__all__' + # fields = '__all__' + fields = ('id', 'contributor', 'absolute_url', 'change') diff --git a/apps/moderation/api/views.py b/apps/moderation/api/views.py index 8744b1972..9aead8f87 100644 --- a/apps/moderation/api/views.py +++ b/apps/moderation/api/views.py @@ -1,15 +1,26 @@ +from typing import TYPE_CHECKING + +from rest_framework import permissions from rest_framework.response import Response from rest_framework.views import APIView from apps.moderation.api.serializers import ContentContributionSerializer from apps.moderation.models.contribution import ContentContribution +if TYPE_CHECKING: + from rest_framework.request import Request + class ContentContributionAPIView(APIView): """API endpoint for content contribution.""" - def get(self, request): - """Return the contents contributed""" - results = ContentContribution.objects.filter(contributor=request.user) + permission_classes = [permissions.IsAuthenticated] - return Response([ContentContributionSerializer(result).data for result in results]) + def get(self, request: 'Request'): + """Return the contents contributed""" + contributions = ContentContribution.objects.filter(contributor=request.user) + return ( + Response([ContentContributionSerializer(result).data for result in contributions]) + if contributions + else Response([]) + ) diff --git a/apps/moderation/models/contribution.py b/apps/moderation/models/contribution.py index ce7c78411..b5e172f65 100644 --- a/apps/moderation/models/contribution.py +++ b/apps/moderation/models/contribution.py @@ -2,9 +2,10 @@ from django.db import models from apps.moderation.fields import SerializedObjectField +from core.models import ExtendedModel -class ContentContribution(models.Model): +class ContentContribution(ExtendedModel): """A contribution to a change.""" contributor = models.ForeignKey( @@ -29,6 +30,11 @@ class ContentContribution(models.Model): def __str__(self) -> str: return f'Contribution by {self.contributor} to {self.change} ({self.date_created})' + def get_absolute_url(self): + if self._state.adding: + return '' + return f'/users/{self.contributor.handle}/contributions/{self.pk}' + @classmethod def get_serializer(self): diff --git a/core/models/model.py b/core/models/model.py index 444e48bcc..e76741a1c 100644 --- a/core/models/model.py +++ b/core/models/model.py @@ -2,7 +2,6 @@ import inspect import logging -from pprint import pformat from typing import TYPE_CHECKING, Any, ClassVar, Match, Optional, Pattern, Type, Union import regex @@ -99,6 +98,11 @@ def get_serializer(cls) -> type[Serializer]: serializer = getattr(cls, 'serializer', None) or None return serializer + @property + def absolute_url(self) -> str: + """Return the model instance's absolute URL.""" + return self.get_absolute_url() + @property def admin_url(self) -> str: """Return the model instance's admin URL.""" @@ -191,16 +195,17 @@ def preprocess_html(self, html: str) -> str: def serialize(self) -> dict: """Return the serialized model instance (dictionary).""" - try: - serialized_instance = self.serializer(self).data - except AttributeError as err: - logging.error(f'{err}') - serialized_instance = ModelSerializer(self).data - logging.debug( - f'Serialized {self.__class__.__name__.lower()}:\n' - f'{pformat(serialized_instance)}' - ) - return serialized_instance + return self.get_serializer()(self).data + # try: + # serialized_instance = self.serializer(self).data + # except AttributeError as err: + # logging.error(f'{err}') + # serialized_instance = ModelSerializer(self).data + # logging.debug( + # f'Serialized {self.__class__.__name__.lower()}:\n' + # f'{pformat(serialized_instance)}' + # ) + # return serialized_instance @classmethod def get_object_html( diff --git a/core/models/module.py b/core/models/module.py index 348263f23..335d62904 100644 --- a/core/models/module.py +++ b/core/models/module.py @@ -169,10 +169,6 @@ def preprocess_html(self, html: str) -> str: """ return html - def serialize(self) -> dict: - """Return the serialized model instance (dictionary).""" - return self.get_serializer()(self).data - @classmethod def get_object_html( cls, diff --git a/frontend/components/Navbar.tsx b/frontend/components/Navbar.tsx index b110ada8e..73f705831 100644 --- a/frontend/components/Navbar.tsx +++ b/frontend/components/Navbar.tsx @@ -130,17 +130,13 @@ const GlobalNavbar: FC = ({ menuItems }: GlobalNavbarProps) = accountControls = ( Profile + + My Contributions + Settings - { - <> - - - My Contributions - - - } + {(session.user.isSuperuser && ( <> diff --git a/frontend/components/TodayInHistory.tsx b/frontend/components/TodayInHistory.tsx index 186b342b2..b888ad66d 100644 --- a/frontend/components/TodayInHistory.tsx +++ b/frontend/components/TodayInHistory.tsx @@ -1,5 +1,5 @@ import BigAnchor from "@/components/BigAnchor"; -import { SerpModule } from "@/types/modules"; +import { SerpModule } from "@/types/models"; import { Grid } from "@mui/material"; import { FC } from "react"; import ModuleUnionCard from "./cards/ModuleUnionCard"; diff --git a/frontend/components/__tests__/TodayInHistory.test.tsx b/frontend/components/__tests__/TodayInHistory.test.tsx index 31acb0a20..24a50dc8e 100644 --- a/frontend/components/__tests__/TodayInHistory.test.tsx +++ b/frontend/components/__tests__/TodayInHistory.test.tsx @@ -1,5 +1,5 @@ import TodayInHistory from "@/components/TodayInHistory"; -import { Quote } from "@/types/modules"; +import { Quote } from "@/types/models"; import { render } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import mockRouter from "next-router-mock"; diff --git a/frontend/components/cards/ModuleCard.tsx b/frontend/components/cards/ModuleCard.tsx index 68d5a953f..5973d7f00 100644 --- a/frontend/components/cards/ModuleCard.tsx +++ b/frontend/components/cards/ModuleCard.tsx @@ -1,4 +1,4 @@ -import { Image, ModuleUnion, Source, Topic } from "@/types/modules"; +import { Image, ModuleUnion, Source, Topic } from "@/types/models"; import { Card } from "@mui/material"; import { styled } from "@mui/material/styles"; import { CSSProperties } from "@mui/styles"; diff --git a/frontend/components/cards/ModuleUnionCard.tsx b/frontend/components/cards/ModuleUnionCard.tsx index c6f9d848c..8313b2369 100644 --- a/frontend/components/cards/ModuleUnionCard.tsx +++ b/frontend/components/cards/ModuleUnionCard.tsx @@ -1,4 +1,4 @@ -import { ModuleUnion, Topic } from "@/types/modules"; +import { ModuleUnion, Topic } from "@/types/models"; import { Box } from "@mui/material"; import React, { FC } from "react"; import HTMLEllipsis from "react-lines-ellipsis/lib/html"; diff --git a/frontend/components/details/ModuleDetail.tsx b/frontend/components/details/ModuleDetail.tsx index 9318803d6..9af923015 100644 --- a/frontend/components/details/ModuleDetail.tsx +++ b/frontend/components/details/ModuleDetail.tsx @@ -1,5 +1,5 @@ import PropositionDetail from "@/components/propositions/PropositionDetail"; -import { ModuleUnion } from "@/types/modules"; +import { ModuleUnion } from "@/types/models"; import { useSession } from "next-auth/client"; import { FC } from "react"; import EntityDetail from "../entities/EntityDetail"; diff --git a/frontend/components/details/ModuleLink.tsx b/frontend/components/details/ModuleLink.tsx index 45483c747..2ba866fb3 100644 --- a/frontend/components/details/ModuleLink.tsx +++ b/frontend/components/details/ModuleLink.tsx @@ -1,5 +1,5 @@ import ModuleModal from "@/components/details/ModuleModal"; -import { ModuleUnion } from "@/types/modules"; +import { ModuleUnion } from "@/types/models"; import { styled } from "@mui/material/styles"; import axios from "axios"; import { useRouter } from "next/router"; diff --git a/frontend/components/details/ModuleModal.tsx b/frontend/components/details/ModuleModal.tsx index 5e3a6b6c2..30d9fac62 100644 --- a/frontend/components/details/ModuleModal.tsx +++ b/frontend/components/details/ModuleModal.tsx @@ -1,6 +1,6 @@ import ModuleDetail from "@/components/details/ModuleDetail"; import { GlobalTheme } from "@/pages/_app.page"; -import { ModuleUnion } from "@/types/modules"; +import { ModuleUnion } from "@/types/models"; import CloseIcon from "@mui/icons-material/Close"; import { Button, diff --git a/frontend/components/entities/EntityDetail.tsx b/frontend/components/entities/EntityDetail.tsx index 869a7f17b..533491bd0 100644 --- a/frontend/components/entities/EntityDetail.tsx +++ b/frontend/components/entities/EntityDetail.tsx @@ -1,5 +1,5 @@ import ModuleHTML from "@/components/details/ModuleHTML"; -import { Entity } from "@/types/modules"; +import { Entity } from "@/types/models"; import { FC } from "react"; import ImageCard from "../images/ImageCard"; diff --git a/frontend/components/images/ImageCard.tsx b/frontend/components/images/ImageCard.tsx index 08d1a8c9a..707709e9d 100644 --- a/frontend/components/images/ImageCard.tsx +++ b/frontend/components/images/ImageCard.tsx @@ -1,4 +1,4 @@ -import { Image } from "@/types/modules"; +import { Image } from "@/types/models"; import { styled } from "@mui/material/styles"; import { FC } from "react"; import HTMLEllipsis from "react-lines-ellipsis/lib/html"; diff --git a/frontend/components/images/ImageDetail.tsx b/frontend/components/images/ImageDetail.tsx index b8630a9ff..65aff733c 100644 --- a/frontend/components/images/ImageDetail.tsx +++ b/frontend/components/images/ImageDetail.tsx @@ -1,4 +1,4 @@ -import { Image } from "@/types/modules"; +import { Image } from "@/types/models"; import { FC } from "react"; import ImageCard from "./ImageCard"; diff --git a/frontend/components/propositions/ArgumentSet.tsx b/frontend/components/propositions/ArgumentSet.tsx index 372654535..55404ff4b 100644 --- a/frontend/components/propositions/ArgumentSet.tsx +++ b/frontend/components/propositions/ArgumentSet.tsx @@ -1,4 +1,4 @@ -import { Argument } from "@/types/modules"; +import { Argument } from "@/types/models"; import { TreeItem, TreeView } from "@mui/lab"; import { TreeItemProps } from "@mui/lab/TreeItem"; import { alpha, Theme } from "@mui/material"; diff --git a/frontend/components/propositions/InlineProposition.tsx b/frontend/components/propositions/InlineProposition.tsx index 986bb9123..9f6b07bdc 100644 --- a/frontend/components/propositions/InlineProposition.tsx +++ b/frontend/components/propositions/InlineProposition.tsx @@ -1,4 +1,4 @@ -import { Proposition } from "@/types/modules"; +import { Proposition } from "@/types/models"; import Link from "next/link"; import { FC } from "react"; diff --git a/frontend/components/propositions/OccurrenceDetail.tsx b/frontend/components/propositions/OccurrenceDetail.tsx index 7f6aee0de..da4e08256 100644 --- a/frontend/components/propositions/OccurrenceDetail.tsx +++ b/frontend/components/propositions/OccurrenceDetail.tsx @@ -1,5 +1,5 @@ import ModuleHTML from "@/components/details/ModuleHTML"; -import { Occurrence } from "@/types/modules"; +import { Occurrence } from "@/types/models"; import { FC } from "react"; import ImageCard from "../images/ImageCard"; import TagList from "../topics/TagList"; diff --git a/frontend/components/propositions/PropositionDetail.tsx b/frontend/components/propositions/PropositionDetail.tsx index 09bfba57e..989ff3b1e 100644 --- a/frontend/components/propositions/PropositionDetail.tsx +++ b/frontend/components/propositions/PropositionDetail.tsx @@ -1,6 +1,6 @@ import ModuleHTML from "@/components/details/ModuleHTML"; import TagList from "@/components/topics/TagList"; -import { Proposition } from "@/types/modules"; +import { Proposition } from "@/types/models"; import { Box } from "@mui/material"; import Slider from "@mui/material/Slider"; import { useSession } from "next-auth/client"; diff --git a/frontend/components/quotes/QuoteDetail.tsx b/frontend/components/quotes/QuoteDetail.tsx index b18ea02ce..453443551 100644 --- a/frontend/components/quotes/QuoteDetail.tsx +++ b/frontend/components/quotes/QuoteDetail.tsx @@ -1,5 +1,5 @@ import ModuleHTML from "@/components/details/ModuleHTML"; -import { Quote } from "@/types/modules"; +import { Quote } from "@/types/models"; import { FC } from "react"; import ImageCard from "../images/ImageCard"; import TagList from "../topics/TagList"; diff --git a/frontend/components/search/Timeline.tsx b/frontend/components/search/Timeline.tsx index a997291ba..b800c0239 100644 --- a/frontend/components/search/Timeline.tsx +++ b/frontend/components/search/Timeline.tsx @@ -1,4 +1,4 @@ -import { SerpModule } from "@/types/modules"; +import { SerpModule } from "@/types/models"; import Compress from "@mui/icons-material/Compress"; import { Box, diff --git a/frontend/components/sources/SourceDetail.tsx b/frontend/components/sources/SourceDetail.tsx index c256c02bf..98a790d44 100644 --- a/frontend/components/sources/SourceDetail.tsx +++ b/frontend/components/sources/SourceDetail.tsx @@ -1,5 +1,5 @@ import Citation from "@/components/sources/Citation"; -import { Source } from "@/types/modules"; +import { Source } from "@/types/models"; import { FC } from "react"; import TagList from "../topics/TagList"; diff --git a/frontend/components/topics/Tag.tsx b/frontend/components/topics/Tag.tsx index df8d9dcfd..2e416288c 100644 --- a/frontend/components/topics/Tag.tsx +++ b/frontend/components/topics/Tag.tsx @@ -1,4 +1,4 @@ -import { Topic } from "@/types/modules"; +import { Topic } from "@/types/models"; import Chip from "@mui/material/Chip"; import { styled } from "@mui/material/styles"; import Link from "next/link"; diff --git a/frontend/components/topics/TagList.tsx b/frontend/components/topics/TagList.tsx index b725e6bc5..841384f04 100644 --- a/frontend/components/topics/TagList.tsx +++ b/frontend/components/topics/TagList.tsx @@ -1,4 +1,4 @@ -import { Topic } from "@/types/modules"; +import { Topic } from "@/types/models"; import { FC } from "react"; import Tag from "./Tag"; diff --git a/frontend/components/topics/TopicDetail.tsx b/frontend/components/topics/TopicDetail.tsx index e1c9653ff..1dab4cc5f 100644 --- a/frontend/components/topics/TopicDetail.tsx +++ b/frontend/components/topics/TopicDetail.tsx @@ -1,6 +1,6 @@ import ModuleCard from "@/components/cards/ModuleCard"; import ModuleHTML from "@/components/details/ModuleHTML"; -import { Topic } from "@/types/modules"; +import { Topic } from "@/types/models"; import { FC } from "react"; import HTMLEllipsis from "react-lines-ellipsis/lib/html"; diff --git a/frontend/pages/[...path].page.tsx b/frontend/pages/[...path].page.tsx index 41d8148f2..442733d29 100644 --- a/frontend/pages/[...path].page.tsx +++ b/frontend/pages/[...path].page.tsx @@ -1,5 +1,5 @@ import Layout from "@/components/Layout"; -import { FlatPage as FlatPageType } from "@/types/modules"; +import { FlatPage as FlatPageType } from "@/types/models"; import { Container, useMediaQuery } from "@mui/material"; import axios from "axios"; import { GetStaticPaths, GetStaticProps } from "next"; diff --git a/frontend/pages/__tests__/search.test.tsx b/frontend/pages/__tests__/search.test.tsx index 0405aa8ee..d6b04dcec 100644 --- a/frontend/pages/__tests__/search.test.tsx +++ b/frontend/pages/__tests__/search.test.tsx @@ -1,5 +1,5 @@ import SearchPage, { SearchProps } from "@/pages/search.page"; -import type { Quote } from "@/types/modules"; +import type { Quote } from "@/types/models"; import { createTheme, ThemeProvider } from "@mui/material/styles"; import { Partial } from "@react-spring/types"; import { render, screen } from "@testing-library/react"; diff --git a/frontend/pages/collections/[slug].page.tsx b/frontend/pages/collections/[slug].page.tsx index bb836ec50..8c00905fa 100644 --- a/frontend/pages/collections/[slug].page.tsx +++ b/frontend/pages/collections/[slug].page.tsx @@ -1,6 +1,6 @@ import ModuleUnionCard from "@/components/cards/ModuleUnionCard"; import Layout from "@/components/Layout"; -import { Collection } from "@/types/modules"; +import { Collection } from "@/types/models"; import ShareIcon from "@mui/icons-material/Share"; import { Box, Button, Container, useMediaQuery } from "@mui/material"; import Grid from "@mui/material/Grid"; diff --git a/frontend/pages/collections/index.page.tsx b/frontend/pages/collections/index.page.tsx index 31e1f2836..8c06a9fbe 100644 --- a/frontend/pages/collections/index.page.tsx +++ b/frontend/pages/collections/index.page.tsx @@ -2,7 +2,7 @@ import axiosWithoutAuth from "@/axiosWithoutAuth"; import Layout from "@/components/Layout"; import PageHeader from "@/components/PageHeader"; import Pagination from "@/components/Pagination"; -import { Collection } from "@/types/modules"; +import { Collection } from "@/types/models"; import { CardContent } from "@mui/material"; import Grid from "@mui/material/Grid"; import { GetServerSideProps } from "next"; diff --git a/frontend/pages/entities/[slug].page.tsx b/frontend/pages/entities/[slug].page.tsx index eeedc2017..c885d0856 100644 --- a/frontend/pages/entities/[slug].page.tsx +++ b/frontend/pages/entities/[slug].page.tsx @@ -2,7 +2,7 @@ import axiosWithoutAuth from "@/axiosWithoutAuth"; import ModuleContainer from "@/components/details/ModuleContainer"; import ModuleDetail from "@/components/details/ModuleDetail"; import Layout from "@/components/Layout"; -import { Entity } from "@/types/modules"; +import { Entity } from "@/types/models"; import { Card, CardContent, CardHeader, styled } from "@mui/material"; import { GetStaticPaths, GetStaticProps } from "next"; import { NextSeo } from "next-seo"; diff --git a/frontend/pages/entities/index.page.tsx b/frontend/pages/entities/index.page.tsx index 84c7f9cb3..62c573c80 100644 --- a/frontend/pages/entities/index.page.tsx +++ b/frontend/pages/entities/index.page.tsx @@ -3,7 +3,7 @@ import ModuleUnionCard from "@/components/cards/ModuleUnionCard"; import Layout from "@/components/Layout"; import PageHeader from "@/components/PageHeader"; import Pagination from "@/components/Pagination"; -import { Entity } from "@/types/modules"; +import { Entity } from "@/types/models"; import Container from "@mui/material/Container"; import Grid from "@mui/material/Grid"; import { GetServerSideProps } from "next"; diff --git a/frontend/pages/images/[slug].page.tsx b/frontend/pages/images/[slug].page.tsx index 43d315589..cf56c8ecc 100644 --- a/frontend/pages/images/[slug].page.tsx +++ b/frontend/pages/images/[slug].page.tsx @@ -2,7 +2,7 @@ import axiosWithoutAuth from "@/axiosWithoutAuth"; import ModuleContainer from "@/components/details/ModuleContainer"; import ModuleDetail from "@/components/details/ModuleDetail"; import Layout from "@/components/Layout"; -import { Image } from "@/types/modules"; +import { Image } from "@/types/models"; import { GetStaticPaths, GetStaticProps } from "next"; import { NextSeo } from "next-seo"; import { FC } from "react"; diff --git a/frontend/pages/images/index.page.tsx b/frontend/pages/images/index.page.tsx index cbc24be65..3a39117da 100644 --- a/frontend/pages/images/index.page.tsx +++ b/frontend/pages/images/index.page.tsx @@ -3,7 +3,7 @@ import ImageCard from "@/components/images/ImageCard"; import Layout from "@/components/Layout"; import PageHeader from "@/components/PageHeader"; import Pagination from "@/components/Pagination"; -import { Image } from "@/types/modules"; +import { Image } from "@/types/models"; import Container from "@mui/material/Container"; import Grid from "@mui/material/Grid"; import { GetServerSideProps } from "next"; diff --git a/frontend/pages/index.page.tsx b/frontend/pages/index.page.tsx index f337a0ac5..c114664e6 100644 --- a/frontend/pages/index.page.tsx +++ b/frontend/pages/index.page.tsx @@ -2,7 +2,7 @@ import ModuleUnionCard from "@/components/cards/ModuleUnionCard"; import Layout from "@/components/Layout"; import SearchButton from "@/components/search/SearchButton"; import TodayInHistory, { TodayInHistoryProps } from "@/components/TodayInHistory"; -import { SerpModule } from "@/types/modules"; +import { SerpModule } from "@/types/models"; import CloseIcon from "@mui/icons-material/Close"; import { Box, Button, CardHeader, Divider, Grid, Link } from "@mui/material"; import Card from "@mui/material/Card"; diff --git a/frontend/pages/occurrences/[slug].page.tsx b/frontend/pages/occurrences/[slug].page.tsx index 44077da19..6e56c3b27 100644 --- a/frontend/pages/occurrences/[slug].page.tsx +++ b/frontend/pages/occurrences/[slug].page.tsx @@ -1,7 +1,7 @@ import ModuleContainer from "@/components/details/ModuleContainer"; import ModuleDetail from "@/components/details/ModuleDetail"; import Layout from "@/components/Layout"; -import { Occurrence } from "@/types/modules"; +import { Occurrence } from "@/types/models"; import axios from "axios"; import { GetStaticPaths, GetStaticProps } from "next"; import { NextSeo } from "next-seo"; diff --git a/frontend/pages/occurrences/index.page.tsx b/frontend/pages/occurrences/index.page.tsx index 6c1bd1ea8..9651e9bd0 100644 --- a/frontend/pages/occurrences/index.page.tsx +++ b/frontend/pages/occurrences/index.page.tsx @@ -3,7 +3,7 @@ import ModuleUnionCard from "@/components/cards/ModuleUnionCard"; import Layout from "@/components/Layout"; import PageHeader from "@/components/PageHeader"; import Pagination from "@/components/Pagination"; -import { Occurrence } from "@/types/modules"; +import { Occurrence } from "@/types/models"; import Container from "@mui/material/Container"; import Grid from "@mui/material/Grid"; import { GetServerSideProps } from "next"; diff --git a/frontend/pages/propositions/[slug].page.tsx b/frontend/pages/propositions/[slug].page.tsx index 8bf455789..a69c23428 100644 --- a/frontend/pages/propositions/[slug].page.tsx +++ b/frontend/pages/propositions/[slug].page.tsx @@ -1,7 +1,7 @@ import axiosWithoutAuth from "@/axiosWithoutAuth"; import Layout from "@/components/Layout"; import PropositionDetail from "@/components/propositions/PropositionDetail"; -import { Proposition } from "@/types/modules"; +import { Proposition } from "@/types/models"; import { Button, Grid } from "@mui/material"; import { GetStaticPaths, GetStaticProps } from "next"; import { NextSeo } from "next-seo"; diff --git a/frontend/pages/propositions/index.page.tsx b/frontend/pages/propositions/index.page.tsx index 434d2df68..c72f79a79 100644 --- a/frontend/pages/propositions/index.page.tsx +++ b/frontend/pages/propositions/index.page.tsx @@ -1,7 +1,7 @@ import axiosWithoutAuth from "@/axiosWithoutAuth"; import Layout from "@/components/Layout"; import PageHeader from "@/components/PageHeader"; -import { Proposition } from "@/types/modules"; +import { Proposition } from "@/types/models"; import Container from "@mui/material/Container"; import List from "@mui/material/List"; import ListItem from "@mui/material/ListItem"; diff --git a/frontend/pages/quotes/[slug].page.tsx b/frontend/pages/quotes/[slug].page.tsx index 77d59799c..5e3584fcd 100644 --- a/frontend/pages/quotes/[slug].page.tsx +++ b/frontend/pages/quotes/[slug].page.tsx @@ -1,7 +1,7 @@ import ModuleContainer from "@/components/details/ModuleContainer"; import ModuleDetail from "@/components/details/ModuleDetail"; import Layout from "@/components/Layout"; -import { Quote } from "@/types/modules"; +import { Quote } from "@/types/models"; import axios from "axios"; import { GetStaticPaths, GetStaticProps } from "next"; import { NextSeo } from "next-seo"; diff --git a/frontend/pages/quotes/index.page.tsx b/frontend/pages/quotes/index.page.tsx index 360620310..ad88b95f2 100644 --- a/frontend/pages/quotes/index.page.tsx +++ b/frontend/pages/quotes/index.page.tsx @@ -3,7 +3,7 @@ import ModuleUnionCard from "@/components/cards/ModuleUnionCard"; import Layout from "@/components/Layout"; import PageHeader from "@/components/PageHeader"; import Pagination from "@/components/Pagination"; -import { Quote } from "@/types/modules"; +import { Quote } from "@/types/models"; import Container from "@mui/material/Container"; import Grid from "@mui/material/Grid"; import { GetServerSideProps } from "next"; diff --git a/frontend/pages/search.page.tsx b/frontend/pages/search.page.tsx index 828213619..57999a230 100644 --- a/frontend/pages/search.page.tsx +++ b/frontend/pages/search.page.tsx @@ -6,7 +6,7 @@ import Layout from "@/components/Layout"; import Pagination from "@/components/Pagination"; import type { TimelineProps } from "@/components/search/Timeline"; import { GlobalTheme } from "@/pages/_app.page"; -import { SerpModule } from "@/types/modules"; +import { SerpModule } from "@/types/models"; import { Box, Container, Drawer, styled, useMediaQuery } from "@mui/material"; import axios from "axios"; import { GetServerSideProps } from "next"; diff --git a/frontend/pages/sources/[slug].page.tsx b/frontend/pages/sources/[slug].page.tsx index c66f5ccde..b79855592 100644 --- a/frontend/pages/sources/[slug].page.tsx +++ b/frontend/pages/sources/[slug].page.tsx @@ -2,7 +2,7 @@ import axiosWithoutAuth from "@/axiosWithoutAuth"; import ModuleContainer from "@/components/details/ModuleContainer"; import ModuleDetail from "@/components/details/ModuleDetail"; import Layout from "@/components/Layout"; -import { Source } from "@/types/modules"; +import { Source } from "@/types/models"; import { GetStaticPaths, GetStaticProps } from "next"; import { NextSeo } from "next-seo"; import { FC } from "react"; diff --git a/frontend/pages/sources/index.page.tsx b/frontend/pages/sources/index.page.tsx index 4aaa0d160..a9469a8e7 100644 --- a/frontend/pages/sources/index.page.tsx +++ b/frontend/pages/sources/index.page.tsx @@ -3,7 +3,7 @@ import Layout from "@/components/Layout"; import PageHeader from "@/components/PageHeader"; import Pagination from "@/components/Pagination"; import Citation from "@/components/sources/Citation"; -import { Source } from "@/types/modules"; +import { Source } from "@/types/models"; import Container from "@mui/material/Container"; import Paper from "@mui/material/Paper"; import Table from "@mui/material/Table"; diff --git a/frontend/pages/topics/[slug].page.tsx b/frontend/pages/topics/[slug].page.tsx index 5bf65a08c..b4f981824 100644 --- a/frontend/pages/topics/[slug].page.tsx +++ b/frontend/pages/topics/[slug].page.tsx @@ -2,7 +2,7 @@ import axiosWithoutAuth from "@/axiosWithoutAuth"; import ModuleContainer from "@/components/details/ModuleContainer"; import Layout from "@/components/Layout"; import PageHeader from "@/components/PageHeader"; -import { Topic } from "@/types/modules"; +import { Topic } from "@/types/models"; import { Card, CardContent, CardHeader, styled } from "@mui/material"; import { GetStaticPaths, GetStaticProps } from "next"; import { NextSeo } from "next-seo"; diff --git a/frontend/pages/topics/index.page.tsx b/frontend/pages/topics/index.page.tsx index 4d4c6d156..3979b7b46 100644 --- a/frontend/pages/topics/index.page.tsx +++ b/frontend/pages/topics/index.page.tsx @@ -1,6 +1,6 @@ import Layout from "@/components/Layout"; import PageHeader from "@/components/PageHeader"; -import { ModuleUnion, Topic } from "@/types/modules"; +import { ModuleUnion, Topic } from "@/types/models"; import { Divider } from "@mui/material"; import Button from "@mui/material/Button"; import Container from "@mui/material/Container"; diff --git a/frontend/pages/users/[handle]/contributions.page.tsx b/frontend/pages/users/[handle]/contributions.page.tsx index 9b93de88c..7e42db23b 100644 --- a/frontend/pages/users/[handle]/contributions.page.tsx +++ b/frontend/pages/users/[handle]/contributions.page.tsx @@ -1,6 +1,6 @@ -import axiosWithoutAuth from "@/axiosWithoutAuth"; -import ModuleUnionCard from "@/components/cards/ModuleUnionCard"; +import axiosWithAuth from "@/axiosWithAuth"; import Layout from "@/components/Layout"; +import { ContentContribution } from "@/types/models"; import { Card, CardContent, CardHeader, Container, Skeleton } from "@mui/material"; import Grid from "@mui/material/Grid"; import Paper from "@mui/material/Paper"; @@ -14,12 +14,14 @@ import Image from "react-bootstrap/Image"; interface UserContributionsPageProps { user?: User; - usercontributions: any[]; + contentContributions: ContentContribution[]; } +const CONTRIBUTION_GUIDELINES_URL_PATH = "/about/contributions"; + const UserContributionsPage: FC = ({ user, - usercontributions, + contentContributions, }: UserContributionsPageProps) => { const [session, _loading] = useSession(); if (!user || _loading) return null; @@ -55,12 +57,12 @@ const UserContributionsPage: FC = ({ My Contributions{" "} <> - {usercontributions.length ? ( - usercontributions.map((module, index) => ( + {contentContributions.length ? ( + contentContributions.map((contribution, index) => ( - + - + {`#${contribution.id} to ${contribution.change.contentObject.title}`} @@ -75,10 +77,16 @@ const UserContributionsPage: FC = ({ ) : ( -

- Sorry! There are no content contributions made. If you`'`d like to - contribute, please visit (link). -

+
+

You have not contributed to any contributions yet.

+

+ Before making content contributions, please read the{" "} + + contribution guidelines + + . +

+
)} @@ -96,7 +104,7 @@ export default UserContributionsPage; // https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering export const getServerSideProps: GetServerSideProps = async (context) => { const session = await getSession(context); - let usercontributions: UserContributionsPageProps[] = []; + let contentContributions: UserContributionsPageProps[] = []; if (!session?.user) { return { redirect: { @@ -105,17 +113,21 @@ export const getServerSideProps: GetServerSideProps = async (context) => { }, }; } - await axiosWithoutAuth - .get("http://django:8000/api/moderation/contributions/") + await axiosWithAuth + .get("http://django:8000/api/moderation/contributions/", { + headers: { + Authorization: `Bearer ${session.accessToken}`, + }, + }) .then((response) => { - usercontributions = response.data; + contentContributions = response.data; }) .catch((error) => { console.error(error); }); return { props: { - usercontributions, + contentContributions, user: session?.user ?? null, }, }; diff --git a/frontend/types/modules.d.ts b/frontend/types/models.d.ts similarity index 96% rename from frontend/types/modules.d.ts rename to frontend/types/models.d.ts index 070e7b038..744f6d61a 100644 --- a/frontend/types/modules.d.ts +++ b/frontend/types/models.d.ts @@ -153,6 +153,13 @@ export interface Change { unchangedObject?: ModuleUnion; } +export interface ContentContribution { + id: number; + absoluteUrl: string; + contributor: User; + change: Change; +} + export interface Issue { id: number; url: string; From 5568ff86ff111747d2288cfdc5894e7bb7440496 Mon Sep 17 00:00:00 2001 From: Jacob Fredericksen Date: Wed, 8 Dec 2021 18:33:20 -0600 Subject: [PATCH 6/7] update type --- frontend/types/models.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/types/models.d.ts b/frontend/types/models.d.ts index 744f6d61a..41e4b8d90 100644 --- a/frontend/types/models.d.ts +++ b/frontend/types/models.d.ts @@ -149,6 +149,7 @@ export interface Change { url: string; initiator: User; description: string; + contentObject?: ModuleUnion; changedObject?: ModuleUnion; unchangedObject?: ModuleUnion; } From 910cd14b48aa2dde0d10461b37a4b9c1cde2c558 Mon Sep 17 00:00:00 2001 From: Jacob Fredericksen Date: Wed, 8 Dec 2021 18:34:53 -0600 Subject: [PATCH 7/7] type fix --- frontend/pages/users/[handle]/contributions.page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/pages/users/[handle]/contributions.page.tsx b/frontend/pages/users/[handle]/contributions.page.tsx index 7e42db23b..18a9c06f0 100644 --- a/frontend/pages/users/[handle]/contributions.page.tsx +++ b/frontend/pages/users/[handle]/contributions.page.tsx @@ -62,7 +62,7 @@ const UserContributionsPage: FC = ({ - {`#${contribution.id} to ${contribution.change.contentObject.title}`} + {`#${contribution.id} to ${contribution.change.contentObject?.title}`}