diff --git a/services/frontend/src/pages/Review/components/review-card.tsx b/services/frontend/src/pages/Review/components/review-card.tsx
new file mode 100644
index 0000000..75003f8
--- /dev/null
+++ b/services/frontend/src/pages/Review/components/review-card.tsx
@@ -0,0 +1,37 @@
+import { Review, ReviewStatus } from "@/shared/types/review";
+import dayjs from "dayjs";
+
+interface ReviewCardProps {
+ review: Review;
+}
+
+export const ReviewCard = ({ review }: ReviewCardProps) => {
+ const id = review.id.split("-").at(-1)?.slice(0, 6);
+
+ return (
+
+
+
+ {review.competition_name}
+
+
{review.task_title}
+
+
+
+
{id}
+
•
+
+ {review.review_status === ReviewStatus.NOT_CHECKED
+ ? `Дата посылки: ${dayjs(review.submitted_at).format("D MMMM, HH:mm")}`
+ : `Дата проверки: ${review.checked_at}`}
+
+
+
+ {review.review_status === ReviewStatus.NOT_CHECKED
+ ? "Не проверено"
+ : ""}
+
+
+
+ );
+};
diff --git a/services/frontend/src/pages/Review/index.tsx b/services/frontend/src/pages/Review/index.tsx
index 233b3c0..0701e14 100644
--- a/services/frontend/src/pages/Review/index.tsx
+++ b/services/frontend/src/pages/Review/index.tsx
@@ -3,7 +3,10 @@ import { getReviewer, getReviewerSubmissions } from "@/shared/api/review";
import { useQuery } from "@tanstack/react-query";
import { useNavigate, useParams } from "react-router";
import { ReviewHeader } from "./modules/review-header";
-import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
+import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
+import { ReviewsList } from "./modules/reviews-list";
+import React from "react";
+import { ReviewStatus } from "@/shared/types/review";
const ReviewPage = () => {
const { token } = useParams<{ token: string }>();
@@ -20,6 +23,22 @@ const ReviewPage = () => {
retry: 0,
});
+ const availableReviews = React.useMemo(
+ () =>
+ (submissionsQuery.data?.submissions || []).filter(
+ (s) => s.review_status === ReviewStatus.NOT_CHECKED,
+ ),
+ [submissionsQuery.data],
+ );
+
+ const checkedReviews = React.useMemo(
+ () =>
+ (submissionsQuery.data?.submissions || []).filter(
+ (s) => s.review_status === ReviewStatus.CHECKED,
+ ),
+ [submissionsQuery.data],
+ );
+
if (reviewerQuery.isLoading || submissionsQuery.isLoading) {
return
;
}
@@ -34,14 +53,35 @@ const ReviewPage = () => {
-
+
-
Посылки
+
Решения
- Доступные
+
+ Доступные
+ {availableReviews.length > 0 && (
+
+ {availableReviews.length}
+
+ )}
+
Проверенные
+
+
+
+
+
+
+
+
diff --git a/services/frontend/src/pages/Review/modules/no-reviews.tsx b/services/frontend/src/pages/Review/modules/no-reviews.tsx
new file mode 100644
index 0000000..f82ec5b
--- /dev/null
+++ b/services/frontend/src/pages/Review/modules/no-reviews.tsx
@@ -0,0 +1,13 @@
+import { Check } from "lucide-react";
+
+export const NoReviews = () => {
+ return (
+