-
-
Location
-
{reviewObj.location}
-
-
-
Hourly Pay
-
${reviewObj.hourlyPay?.toString()}
+
Work model: {reviewObj.workEnvironment}
-
-
Work Model
-
- {prettyWorkEnviornment(
- reviewObj.workEnvironment as WorkEnvironmentType,
- )}
-
-
-
-
Drug Test?
-
{reviewObj.drugTest ? "Yes" : "No"}
+
+
Pay: ${reviewObj.hourlyPay}/hr
-
-
Overtime Common?
-
{reviewObj.overtimeNormal ? "Yes" : "No"}
+
+
+
+
+
+
+
Company Culture
+
+
+
+
Supervisor
+
+
+
+
Interview Rating
+
+
-
-
-
- Benefits
-
- {benefits.map((benefit) => {
- return (
-
- {benefit}
-
- );
- })}
-
- {reviewObj.otherBenefits}
-
+
{reviewObj.textReview}
+
+
);
diff --git a/apps/web/src/app/_components/reviews/role-card-preview.tsx b/apps/web/src/app/_components/reviews/role-card-preview.tsx
new file mode 100644
index 0000000..85b58e0
--- /dev/null
+++ b/apps/web/src/app/_components/reviews/role-card-preview.tsx
@@ -0,0 +1,92 @@
+"use client";
+
+import Image from "next/image";
+
+import type { RoleType } from "@cooper/db/schema";
+import { cn } from "@cooper/ui";
+import { Card, CardContent, CardHeader, CardTitle } from "@cooper/ui/card";
+
+import { api } from "~/trpc/react";
+
+interface RoleCardPreviewProps {
+ className?: string;
+ reviewObj: RoleType;
+}
+
+export function RoleCardPreview({
+ className,
+ reviewObj,
+}: RoleCardPreviewProps) {
+ // ===== COMPANY DATA ===== //
+ const company = api.company.getById.useQuery({
+ id: reviewObj.companyId,
+ });
+
+ // ===== ROLE DATA ===== //
+ const role = api.role.getById.useQuery({ id: reviewObj.id });
+ const reviews = api.review.getByRole.useQuery({ id: reviewObj.id });
+
+ return (
+
+
+
+
+
+
+
+
{role.data?.title}
+
+ Co-op
+
+
+
+
+ {company.data?.name}
+ {reviews.isSuccess && reviews.data.length > 0 && (
+
+ •
+
+ )}
+ {reviews.isSuccess && reviews.data.length > 0 && (
+ {reviews.data[0]?.location}
+ )}
+
+
+
+
+
+ {reviews.isSuccess &&
+ reviews.data.length > 0 &&
+ (() => {
+ const totalRating = reviews.data.reduce(
+ (sum, review) => sum + review.overallRating,
+ 0,
+ );
+ const averageRating = (totalRating / reviews.data.length).toFixed(
+ 1,
+ );
+
+ return (
+
+
+ {averageRating} ({reviews.data.length} reviews)
+
+ );
+ })()}
+
+
+
+ );
+}
diff --git a/apps/web/src/app/_components/reviews/role-info.tsx b/apps/web/src/app/_components/reviews/role-info.tsx
new file mode 100644
index 0000000..830c40a
--- /dev/null
+++ b/apps/web/src/app/_components/reviews/role-info.tsx
@@ -0,0 +1,237 @@
+"use client";
+
+import Image from "next/image";
+
+import type { RoleType } from "@cooper/db/schema";
+import { cn } from "@cooper/ui";
+import { Card, CardContent, CardHeader, CardTitle } from "@cooper/ui/card";
+
+import { api } from "~/trpc/react";
+import { ReviewCard } from "./review-card";
+import { ReviewCardStars } from "./review-card-stars";
+
+// const InterviewDifficulty = [
+// { des: "Very Easy", color: "text-[#4bc92e]" },
+// { des: "Easy", color: "text-[#09b52b]" },
+// { des: "Neither Easy Nor Difficult", color: "text-cooper-blue-400" },
+// { des: "Difficult", color: "text-[#f27c38]" },
+// { des: "Very Difficult", color: "text-[#f52536]" },
+// ];
+
+interface RoleCardProps {
+ className?: string;
+ roleObj: RoleType;
+}
+
+export function RoleInfo({ className, roleObj }: RoleCardProps) {
+ const reviews = api.review.getByRole.useQuery({ id: roleObj.id });
+
+ const companyQuery = api.company.getById.useQuery(
+ { id: reviews.data?.[0]?.companyId ?? "" },
+ { enabled: !!reviews.data?.[0]?.companyId },
+ );
+
+ // ===== ROLE DATA ===== //
+ const role = api.role.getById.useQuery({ id: roleObj.id });
+
+ const companyData = companyQuery.data;
+
+ return (
+
+
+
+
+
+ {companyData ? (
+
+ ) : (
+
+ )}
+
+
+
+
{role.data?.title}
+
+ Co-op
+
+
+
+
+ {companyData?.name}
+ {reviews.isSuccess && reviews.data.length > 0 && (
+
+ •
+
+ )}
+ {reviews.isSuccess && reviews.data.length > 0 && (
+ {reviews.data[0]?.location}
+ )}
+
+
+
+
+
+ {reviews.isSuccess &&
+ reviews.data.length > 0 &&
+ (() => {
+ const totalRating = reviews.data.reduce(
+ (sum, review) => sum + review.overallRating,
+ 0,
+ );
+ const averageRating = (
+ totalRating / reviews.data.length
+ ).toFixed(1);
+
+ return (
+
+
+ {averageRating} ({reviews.data.length} reviews)
+
+ );
+ })()}
+
+
+
+
+
+ About the Job
+
+
+ {reviews.isSuccess &&
+ reviews.data.length > 0 &&
+ (() => {
+ const totalPay = reviews.data.reduce(
+ (sum, review) =>
+ sum + parseFloat(review.hourlyPay ?? "0"),
+ 0.0,
+ );
+ const averagePay = totalPay / reviews.data.length;
+
+ return (
+ <>
+ Pay Range
+
+ ${Math.round(averagePay * 100) / 100.0}/hr
+
+ >
+ );
+ })()}
+
+
+ {reviews.isSuccess &&
+ reviews.data.length > 0 &&
+ (() => {
+ const totalInterviewDifficulty = reviews.data.reduce(
+ (sum, review) => sum + review.interviewDifficulty,
+ 0,
+ );
+ const averageInterviewDifficulty =
+ totalInterviewDifficulty / reviews.data.length;
+ return (
+ <>
+
+ Interview Difficulty
+
+
+ {Math.round(averageInterviewDifficulty * 100) / 100.0}
+
+ >
+ );
+ })()}
+
+
+
+
+
+
+ Ratings
+
+ {reviews.isSuccess &&
+ reviews.data.length > 0 &&
+ (() => {
+ const totalCultureRating = reviews.data.reduce(
+ (sum, review) => sum + review.cultureRating,
+ 0,
+ );
+ const averageCultureRating =
+ totalCultureRating / reviews.data.length;
+ return (
+ <>
+
+
Company Culture
+
+
+ >
+ );
+ })()}
+ {reviews.isSuccess &&
+ reviews.data.length > 0 &&
+ (() => {
+ const totalSupervisorRating = reviews.data.reduce(
+ (sum, review) => sum + review.supervisorRating,
+ 0,
+ );
+ const averageSupervisorRating =
+ totalSupervisorRating / reviews.data.length;
+ return (
+ <>
+
+
Supervisor
+
+
+ >
+ );
+ })()}
+ {reviews.isSuccess &&
+ reviews.data.length > 0 &&
+ (() => {
+ const totalInterviewRating = reviews.data.reduce(
+ (sum, review) => sum + review.interviewRating,
+ 0,
+ );
+ const averageInterviewRating =
+ totalInterviewRating / reviews.data.length;
+ return (
+ <>
+
+
Interview Rating
+
+
+ >
+ );
+ })()}
+
+
+
+ {reviews.isSuccess && reviews.data.length > 0 && (
+
+
Reviews:
+
+ {reviews.data.map((review) => {
+ return
;
+ })}
+
+ )}
+
+
+
+ );
+}
diff --git a/apps/web/src/app/_components/search/search-bar.tsx b/apps/web/src/app/_components/search/review-search-bar.tsx
similarity index 85%
rename from apps/web/src/app/_components/search/search-bar.tsx
rename to apps/web/src/app/_components/search/review-search-bar.tsx
index 1c0ba5e..c6371d4 100644
--- a/apps/web/src/app/_components/search/search-bar.tsx
+++ b/apps/web/src/app/_components/search/review-search-bar.tsx
@@ -27,7 +27,7 @@ interface SearchBarProps {
* @param param0 Cycle and Term to be set as default values for their respective dropdowns
* @returns A search bar which is connected to a parent 'useForm'
*/
-export function SearchBar({ cycle, term }: SearchBarProps) {
+export function ReviewSearchBar({ cycle, term }: SearchBarProps) {
const form = useFormContext();
const [selectedCycle, setSelectedCycle] = useState
(cycle);
@@ -43,7 +43,7 @@ export function SearchBar({ cycle, term }: SearchBarProps) {
@@ -66,7 +66,7 @@ export function SearchBar({ cycle, term }: SearchBarProps) {
}}
value={selectedCycle}
>
-
+
@@ -101,7 +101,7 @@ export function SearchBar({ cycle, term }: SearchBarProps) {
}}
value={selectedTerm}
>
-
+
@@ -121,7 +121,7 @@ export function SearchBar({ cycle, term }: SearchBarProps) {
)}
/>