Skip to content

Commit d766e0f

Browse files
authored
Merge pull request #70 from pennlabs/james/moderation-frontend
add frontend for moderation
2 parents 89508f3 + 810119e commit d766e0f

5 files changed

Lines changed: 39 additions & 4 deletions

File tree

frontend/components/listings/ListingsCard.tsx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import Image from "next/image";
22
import Link from "next/link";
33
import { Calendar } from "lucide-react";
44
import { Badge } from "@/components/ui/badge";
5-
import { formatPrice, formatCondition, formatDate } from "@/lib/utils";
5+
import { formatPrice, formatCondition, formatDate, cn } from "@/lib/utils";
66
import { Item, Sublet } from "@/lib/types";
77

88
const DEFAULT_IMAGE = "/images/default-image.jpg";
@@ -58,7 +58,12 @@ export const ListingsCard = ({ listing, previewImageUrl, href, isMyListing = fal
5858
return (
5959
<Link
6060
href={href}
61-
className="group flex w-full flex-col overflow-hidden rounded-xl border border-gray-200 bg-white transition-all duration-200 hover:shadow-lg"
61+
className={cn(
62+
"group flex w-full flex-col overflow-hidden rounded-xl border bg-white transition-all duration-200 hover:shadow-lg",
63+
isMyListing && listing.status === "PENDING" && "border-amber-300 opacity-70",
64+
isMyListing && listing.status === "REJECTED" && "border-red-300 opacity-50",
65+
!(isMyListing && listing.status !== "APPROVED") && "border-gray-200"
66+
)}
6267
>
6368
{/* image container */}
6469
<div className="relative aspect-square w-full overflow-hidden bg-gray-100">
@@ -77,6 +82,20 @@ export const ListingsCard = ({ listing, previewImageUrl, href, isMyListing = fal
7782
</Badge>
7883
</div>
7984
)}
85+
{isMyListing && listing.status === "PENDING" && (
86+
<div className="absolute top-3 right-3">
87+
<Badge className="border-none bg-amber-500 text-white shadow-sm hover:bg-amber-600">
88+
Under Review
89+
</Badge>
90+
</div>
91+
)}
92+
{isMyListing && listing.status === "REJECTED" && (
93+
<div className="absolute top-3 right-3">
94+
<Badge className="border-none bg-red-500 text-white shadow-sm hover:bg-red-600">
95+
Rejected
96+
</Badge>
97+
</div>
98+
)}
8099
<div className="absolute bottom-3 left-3">
81100
<Badge className="border-none bg-white/90 text-gray-900 shadow-sm backdrop-blur-sm hover:bg-white">
82101
{getBadgeContent(listing)}

frontend/components/listings/detail/ListingDetail.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,16 @@ export const ListingDetail = ({ listingId }: Props) => {
8181
</button>
8282
</div>
8383
</div>
84+
{listing.status === "PENDING" && (
85+
<div className="mb-4 rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800">
86+
This listing is under review and is not yet visible to others.
87+
</div>
88+
)}
89+
{listing.status === "REJECTED" && (
90+
<div className="mb-4 rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-800">
91+
This listing was rejected for violating our content policy and is not visible to others.
92+
</div>
93+
)}
8494
<div className="grid grid-cols-1 gap-8 lg:grid-cols-[minmax(0,1fr)_minmax(0,1fr)]">
8595
<ListingImageGallery images={listing.images} />
8696
<div className="space-y-6">

frontend/components/listings/form/ItemForm.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export function ItemForm() {
5050
const { mutate, isPending } = useMutation({
5151
mutationFn: createListing,
5252
onSuccess: (data) => {
53-
toast.success(`${DISPLAY_LABEL} created successfully!`);
53+
toast.success(`${DISPLAY_LABEL} submitted and is under review.`);
5454
queryClient.invalidateQueries({ queryKey: ["items"] });
5555
reset();
5656
imageUpload.clearImages();

frontend/components/listings/form/SubletForm.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export function SubletForm() {
6060
const { mutate, isPending } = useMutation({
6161
mutationFn: createListing,
6262
onSuccess: (data) => {
63-
toast.success(`${DISPLAY_LABEL} created successfully!`);
63+
toast.success(`${DISPLAY_LABEL} submitted and is under review.`);
6464
queryClient.invalidateQueries({ queryKey: ["sublets"] });
6565
reset();
6666
imageUpload.clearImages();

frontend/lib/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ export type ValidatedAddress = {
109109
placeId: number;
110110
};
111111

112+
// ------------------------------------------------------------
113+
// listing status (content moderation)
114+
// ------------------------------------------------------------
115+
export type ListingStatus = "PENDING" | "APPROVED" | "REJECTED";
116+
112117
// ------------------------------------------------------------
113118
// base listing fields (shared by all listings)
114119
// ------------------------------------------------------------
@@ -126,6 +131,7 @@ type BaseListing = {
126131
favorite_count: number;
127132
is_favorited?: boolean;
128133
seller: User;
134+
status: ListingStatus;
129135
};
130136

131137
// ------------------------------------------------------------

0 commit comments

Comments
 (0)