Skip to content
Merged
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
2 changes: 1 addition & 1 deletion apps/auth-proxy/.output/nitro.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"date": "2025-11-14T23:53:58.107Z",
"date": "2026-02-08T00:37:16.069Z",
"preset": "node-server",
"framework": {
"name": "nitro",
Expand Down
1 change: 1 addition & 0 deletions apps/auth-proxy/.output/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"@panva/hkdf": "1.2.1",
"cookie": "0.6.0",
"jose": "5.6.3",
"node-mock-http": "1.0.4",
"oauth4webapi": "2.11.1",
"preact": "10.11.3",
"preact-render-to-string": "5.2.3",
Expand Down
19 changes: 9 additions & 10 deletions apps/web/src/app/(pages)/(protected)/profile/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,15 @@ export default function Profile() {
const searchParams = useSearchParams();
const tab = searchParams.get("tab") ?? "saved-roles";

const {
data: session,
isLoading: sessionLoading,
error: sessionError,
} = api.auth.getSession.useQuery();
const {
data: profile,
isLoading: profileLoading,
error: profileError,
} = api.profile.getCurrentUser.useQuery();
const sessionQuery = api.auth.getSession.useQuery();
const session = sessionQuery.data;
const sessionLoading = sessionQuery.isLoading;
const sessionError = sessionQuery.error;

const profileQuery = api.profile.getCurrentUser.useQuery();
const profile = profileQuery.data;
const profileLoading = profileQuery.isLoading;
const profileError = profileQuery.error;

useEffect(() => {
if (!sessionLoading && !profileLoading) {
Expand Down
20 changes: 8 additions & 12 deletions apps/web/src/app/(pages)/(protected)/review-form/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ import {
} from "~/app/_components/form/sections";
import { z } from "zod";
import { useCustomToast } from "@cooper/ui";
import { Industry, WorkEnvironment, WorkTerm } from "@cooper/db/schema";
import {
Industry,
WorkEnvironment,
WorkTerm,
JobType,
} from "@cooper/db/schema";
import { Filter } from "bad-words";
import dayjs from "dayjs";
import { Form } from "node_modules/@cooper/ui/src/form";
Expand All @@ -23,16 +28,6 @@ import { Button } from "@cooper/ui/button";

const filter = new Filter();

export const benefits = [
{ field: "pto", label: "PTO" },
{ field: "federalHolidays", label: "Federal holidays off" },
{ field: "freeLunch", label: "Free lunch" },
{ field: "travelBenefits", label: "Travel benefits" },
{ field: "freeMerch", label: "Free merchandise" },
{ field: "snackBar", label: "Snack bar" },
{ field: "employeeLounge", label: "Employee lounge" },
];

const formSchema = z.object({
workTerm: z.nativeEnum(WorkTerm, {
required_error: "You need to select a co-op cycle.",
Expand Down Expand Up @@ -113,7 +108,7 @@ const formSchema = z.object({
locationId: z.string().min(1, {
message: "You need to select a location.",
}),
jobType: z.string().min(1, {
jobType: z.nativeEnum(JobType, {
message: "You need to select a job type.",
}),
hourlyPay: z.coerce
Expand Down Expand Up @@ -184,6 +179,7 @@ export default function ReviewForm() {
interviewReview: "",
textReview: "",
locationId: "",
jobType: undefined,
hourlyPay: "",
workEnvironment: undefined,
drugTest: undefined,
Expand Down
4 changes: 3 additions & 1 deletion apps/web/src/app/_components/companies/company-reviews.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { calculateRatings } from "~/utils/reviewCountByStars";
import StarGraph from "../shared/star-graph";
import CompanyStatistics from "./company-statistics";
import {
calculateJobTypes,
calculatePay,
calculatePayRange,
calculateWorkModels,
Expand All @@ -28,6 +29,7 @@ export function CompanyReview({ companyObj }: CompanyReviewProps) {

const ratings = calculateRatings(reviews.data ?? []);
const workModels = calculateWorkModels(reviews.data ?? []);
const jobTypes = calculateJobTypes(reviews.data ?? []);
const payStats = calculatePay(reviews.data ?? []);
const payRange = calculatePayRange(reviews.data ?? []);

Expand Down Expand Up @@ -56,9 +58,9 @@ export function CompanyReview({ companyObj }: CompanyReviewProps) {
{(reviews.data?.length ?? 0) > 0 && (
<CompanyStatistics
workModels={workModels}
reviews={reviews.data?.length ?? 0}
payStats={payStats}
payRange={payRange}
jobTypes={jobTypes}
/>
)}
</div>
Expand Down
79 changes: 67 additions & 12 deletions apps/web/src/app/_components/companies/company-statistics.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
export default function CompanyStatistics({
workModels,
reviews,
payStats,
payRange,
jobTypes,
}: {
workModels: { name: string; percentage: number; count: number }[];
payStats: { pay: string; percentage: number; count: number }[];
reviews: number;
payRange: { label?: string; min: number; max: number }[];
jobTypes: { name: string; percentage: number; count: number }[];
}) {
const payRangeColors = [
"cooper-yellow-200",
"cooper-blue-400",
"cooper-red-400",
];

const payOrder: Record<string, number> = {
Low: 0,
Pay: 0,
Mid: 1,
High: 2,
};
const jobTypeOrder: Record<string, number> = {
"Co-op": 0,
Internship: 1,
};
const workModelOrder: Record<string, number> = {
"In-person": 0,
Hybrid: 1,
Remote: 2,
};

const payRangesWithData = payRange
.map((range, rangeIndex) => {
const statsInRange = payStats.filter((stat) => {
Expand All @@ -36,24 +52,63 @@ export default function CompanyStatistics({
color: payRangeColors[rangeIndex],
};
})
.filter((item) => item.count > 0);
.filter((item) => item.count > 0)
.sort(
(a, b) =>
(payOrder[a.range.label ?? 3] ?? 3) -
(payOrder[b.range.label ?? 3] ?? 3),
);

const sortedJobTypes = [...jobTypes].sort(
(a, b) => (jobTypeOrder[a.name] ?? 2) - (jobTypeOrder[b.name] ?? 2),
);
const sortedWorkModels = [...workModels].sort(
(a, b) => (workModelOrder[a.name] ?? 3) - (workModelOrder[b.name] ?? 3),
);
return (
<div className="flex flex-col md:flex-row justify-between w-full pt-4 text-cooper-gray-400 gap-4 md:gap-0">
<div className="md:w-[30%]">
<p className="pb-2">Job type</p>
<div className="h-7 flex-1 rounded-lg bg-cooper-yellow-200" />
<div className="flex flex-row items-center pt-2 justify-between">
<div className="flex flex-row items-center">
<div className="w-3.5 h-3.5 rounded-full bg-cooper-yellow-200" />
<div className="pl-2">Co-op</div>
</div>
<div className="pl-2">{reviews}</div>
<div className="h-7 flex-1 rounded-lg flex overflow-hidden gap-0.5">
{sortedJobTypes.map((job) => (
<div
key={job.name}
className={`h-full rounded-lg ${
job.name === "Co-op"
? "bg-cooper-yellow-200"
: job.name === "Internship"
? "bg-cooper-blue-400"
: "bg-cooper-red-400"
}`}
style={{ width: `${job.percentage}%` }}
/>
))}
</div>
{sortedJobTypes.map((job) => (
<div
key={job.name}
className="flex flex-row items-center pt-2 justify-between"
>
<div className="flex flex-row items-center">
<div
className={`w-3.5 h-3.5 rounded-full ${
job.name === "Co-op"
? "bg-cooper-yellow-200"
: job.name === "Internship"
? "bg-cooper-blue-400"
: "bg-cooper-red-400"
}`}
/>
<div className="pl-2">{job.name}</div>
</div>
<div className="pl-2">{job.count}</div>
</div>
))}
</div>
<div className="md:w-[30%]">
<p className="pb-2">Work model</p>
<div className="h-7 flex-1 rounded-lg flex overflow-hidden gap-0.5">
{workModels.map((model) => (
{sortedWorkModels.map((model) => (
<div
key={model.name}
className={`h-full rounded-lg ${
Expand All @@ -68,7 +123,7 @@ export default function CompanyStatistics({
))}
</div>

{workModels.map((workModel) => (
{sortedWorkModels.map((workModel) => (
<div
key={workModel.name}
className="flex flex-row items-center pt-2 justify-between"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ export function BasicInfoSection({
options={[
{ value: "Co-op", label: "Co-op" },
{ value: "Internship", label: "Internship" },
{ value: "Part time", label: "Part time" },
]}
className="w-full border-cooper-gray-150 text-cooper-gray-350 text-sm h-10"
value={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
import { RadioGroup, RadioGroupItem } from "@cooper/ui/radio-group";

import { FormSection } from "~/app/_components/form/form-section";
import { benefits } from "~/app/(pages)/(protected)/review-form/page";
import { Select } from "../../themed/onboarding/select";
import FilterBody from "../../filters/filter-body";

Expand All @@ -21,6 +20,16 @@ import FilterBody from "../../filters/filter-body";
export function CompanyDetailsSection() {
const form = useFormContext();

const benefits = [
{ field: "pto", label: "PTO" },
{ field: "federalHolidays", label: "Federal holidays off" },
{ field: "freeLunch", label: "Free lunch" },
{ field: "travelBenefits", label: "Travel benefits" },
{ field: "freeMerch", label: "Free merchandise" },
{ field: "snackBar", label: "Snack bar" },
{ field: "employeeLounge", label: "Employee lounge" },
];

return (
<FormSection>
<FormField
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,6 @@ export default function ExistingCompanyContent({
description: values.description,
companyId: selectedCompanyId,
createdBy: profileId ?? "",
jobType: "CO-OP",
});
};

Expand Down
3 changes: 2 additions & 1 deletion apps/web/src/app/_components/reviews/review-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ export function ReviewCard({ reviewObj, className }: ReviewCardProps) {
<div className="flex justify-between text-sm">
<div className="flex md:gap-10 gap-6 bg-[#f4f4f4] p-3 md:pl-4 pr-4 rounded-lg">
<div className="flex md:flex-row flex-col gap-2">
<span className="text-cooper-gray-350">Job type</span> Co-op
<span className="text-cooper-gray-350">Job type</span>{" "}
{reviewObj.jobType === "CO-OP" ? "Co-op" : reviewObj.jobType}
</div>
<div className="flex md:flex-row flex-col gap-2">
<span className="text-cooper-gray-350">Work model</span>
Expand Down
22 changes: 19 additions & 3 deletions apps/web/src/app/_components/reviews/role-card-preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,21 @@ export function RoleCardPreview({
},
);

const jobTypesFromReviews = [
...new Set(
(reviews.data ?? [])
.map((r) => r.jobType)
.filter(Boolean)
.map((job) => (job === "CO-OP" ? "Co-op" : job)),
),
] as string[];
const jobTypeLabel =
jobTypesFromReviews.length === 0
? null
: jobTypesFromReviews.length === 1
? jobTypesFromReviews[0]
: jobTypesFromReviews.sort().join(" / ");

return (
<Card
className={cn(
Expand Down Expand Up @@ -77,10 +92,11 @@ export function RoleCardPreview({
<h3 className="text-xl font-semibold leading-tight">
{role.data?.title}
</h3>
<span className="text-base font-normal text-[#999999]">
Co-op
<span className="text-sm font-normal text-[#999999]">
{jobTypeLabel}
</span>
</div>

<div className="flex items-center gap-2 text-base text-[#666666]">
{company.data?.name}
{location.isSuccess && location.data && (
Expand All @@ -103,7 +119,7 @@ export function RoleCardPreview({
) / 100}
</span>
<span>
({reviews.data.length}+ review
({reviews.data.length} review
{reviews.data.length === 1 ? "" : "s"})
</span>
</div>
Expand Down
23 changes: 20 additions & 3 deletions apps/web/src/app/_components/reviews/role-info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,21 @@ export function RoleInfo({ className, roleObj, onBack }: RoleCardProps) {
return ratingMatch && searchMatch;
});

const jobTypesFromReviews = [
...new Set(
(reviews.data ?? [])
.map((r) => r.jobType)
.filter(Boolean)
.map((job) => (job === "CO-OP" ? "Co-op" : job)),
),
] as string[];
const jobTypeLabel =
jobTypesFromReviews.length === 0
? null
: jobTypesFromReviews.length === 1
? jobTypesFromReviews[0]
: jobTypesFromReviews.sort().join(" / ");

return (
<div
className={cn(
Expand Down Expand Up @@ -174,7 +189,7 @@ export function RoleInfo({ className, roleObj, onBack }: RoleCardProps) {
<div className="flex items-center gap-3 text-lg md:text-2xl">
<div>{roleObj.title}</div>
<div className="hidden text-sm font-normal text-cooper-gray-400 sm:block">
Co-op
{jobTypeLabel}
</div>
</div>
</CardTitle>
Expand Down Expand Up @@ -322,8 +337,10 @@ export function RoleInfo({ className, roleObj, onBack }: RoleCardProps) {
<div className="text-cooper-gray-400">Overtime work</div>
<div className="flex items-center gap-2 pl-1">
<div className="text-4xl text-[#141414]">
{Number(averages.data.overtimeNormal.toPrecision(2)) *
100}
{Math.round(
Number(averages.data.overtimeNormal.toPrecision(2)) *
100,
)}
%
</div>
<div className="flex flex-wrap text-sm text-[#141414]">
Expand Down
Loading
Loading