Skip to content

Commit

Permalink
add matrix generation
Browse files Browse the repository at this point in the history
  • Loading branch information
Max-vS committed Jun 17, 2024
2 parents dfe5b29 + 8f79cb7 commit c8f48f6
Show file tree
Hide file tree
Showing 21 changed files with 811 additions and 292 deletions.
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,42 @@ Consider checking out the commands listed in /app/Makefile.

> Please only use them if you know what you are doing!
### Generating mock data

Generate mock users, opportunities, applications and reviews using **faker** scripts.

How to generate mock data:

1. **Run local DB**

```bash
docker-compose up
```

2. **Login via Slack Authentication**

- Open the UI and log in via Slack authentication. This will create a session and a User entry in the DB.

3. **Seed local DB**

- Run the following command to seed the local DB with mock data:

```bash
bun db:seed
```

Command Line Options:

```bash
~ bun db:seed -h
```

Reset/Clear DB:

```bash
~ bun prisma migrate reset
```

### Working on a Linear ticket

Working with Linear tickets is very similar to working with GitHub issues.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,21 @@ export default async function ApplicationOverview({
},
});


const opportunityTitle = db.opportunity.findUnique({
where: {
id: application?.opportunityId,
},
}).then((opportunity) => opportunity?.title);

// TODO: Better handling
if (!application) redirect("/");

return (
<div className="space-y-8 p-8">
<div className="flex justify-between">
<div>
<Breadcrumbs title={`Application: ${application.id}`} />
<Breadcrumbs title={`Application: ${application.id}`} opportunityTitle={await opportunityTitle} />
<h1 className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
Application of ID: {application.id}
</h1>
Expand Down
10 changes: 6 additions & 4 deletions app/opportunities/[opportunity_id]/applications/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,12 @@ export default async function OpportunityOverviewPage({
<div className="space-y-8 p-8">
<div className="flex justify-between">
<div className="flex w-full flex-row items-center justify-between">
<Breadcrumbs title={`Applications: ${opportunity?.title}`} />
<h1 className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
Applications for {opportunity?.title}
</h1>
<div>
<Breadcrumbs title={`Applications`} opportunityTitle={opportunity?.title} />
<h1 className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
Applications for {opportunity?.title}
</h1>
</div>
<div className="flex gap-2">
<ExportButton
opportunityId={Number(params.opportunity_id)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ export const EditOpportunityForm = ({
<div className="flex justify-between">
<div className="flex flex-col gap-3">
<Breadcrumbs
title={"Edit: " + form.getValues().generalInformation.title}
title={"Edit"}
opportunityTitle={form.getValues().generalInformation.title}
/>
<h1 className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
Edit opportunity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ export default async function Review({ params }: ReviewProps) {
include: { application: true, questionnaire: true },
});

const opportunityTitle = db.opportunity.findUnique({
where: {
id: review?.application.opportunityId,
},
}).then((opportunity) => opportunity?.title);

if (!review) redirect("/404");

const questions = review.questionnaire.questions as Question[];
Expand All @@ -31,6 +37,7 @@ export default async function Review({ params }: ReviewProps) {
questions={questions}
application={review.application}
review={review}
opportunityTitle={await opportunityTitle}
/>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ interface ReviewFormProps {
application: Application;
review: Review;
questions: Question[];
opportunityTitle: string | undefined;
}
export const ReviewForm = ({
application,
questions,
review,
opportunityTitle,
}: ReviewFormProps) => {
const applicationFields = (application.content as Tally).data.fields;

Expand Down Expand Up @@ -76,6 +78,7 @@ export const ReviewForm = ({
<div>
<Breadcrumbs
title={`Application: ${application.opportunityId}`}
opportunityTitle={opportunityTitle}
/>
<h1 className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
Review application
Expand Down
32 changes: 19 additions & 13 deletions app/opportunities/[opportunity_id]/review/new/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,29 @@ export default async function StartReview({ params }: StartReviewProps) {
// Iterate over applications to find the first suitable one
for (const application of applications) {
// Find a suitable questionnaire within this application
suitableQuestionnaire = application.questionnaires.find(
(questionnaire) =>
questionnaire.reviewers.some(
(reviewer) => reviewer.id === session.user.id,
) && // User is a reviewer
questionnaire.reviews.filter(
(review) =>
review.userId === session.user.id &&
review.questionnaireId === questionnaire.id &&
review.applicationId === application.id,
).length === 0 && // User has not reviewed questionnaire and application together
suitableQuestionnaire = application.questionnaires.find((questionnaire) => {
// User is a reviewer
const isReviewer = questionnaire.reviewers.some(
(reviewer) => reviewer.id === session.user.id,
);

// User has not reviewed questionnaire and application together
const hasNotReviewed = !questionnaire.reviews.some(
(review) =>
review.userId === session.user.id &&
review.questionnaireId === questionnaire.id &&
review.applicationId === application.id,
);

const lessReviewsThanRequired =
questionnaire.reviews.filter(
(review) =>
review.questionnaireId === questionnaire.id &&
review.applicationId === application.id,
).length < questionnaire.requiredReviews, // Less reviews than required
);
).length < questionnaire.requiredReviews;

return isReviewer && hasNotReviewed && lessReviewsThanRequired;
});

if (suitableQuestionnaire) {
suitableApplication = application;
Expand Down
2 changes: 1 addition & 1 deletion app/opportunities/[opportunity_id]/review/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default async function ReviewPage({ params }: ReviewPageProps) {
<div className="space-y-8 p-8">
<div className="flex justify-between">
<div>
<Breadcrumbs title={`Reviews: ${opportunity?.title}`} />
<Breadcrumbs title={"Reviews"} opportunityTitle={opportunity?.title} />
<h1 className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
Your reviews
</h1>
Expand Down
2 changes: 2 additions & 0 deletions app/profile/components/ProfileOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
} from "@lib/schemas/contact";
import { api } from "trpc/react";
import { toast } from "sonner";
import Breadcrumbs from "@components/ui/breadcrumbs";

interface ProfileOverviewProps {
user: Prisma.UserGetPayload<{ include: { profile: true } }>;
Expand Down Expand Up @@ -200,6 +201,7 @@ export function ProfileOverview({ user, contacts }: ProfileOverviewProps) {
<div className="space-y-8">
<div className="flex flex-col items-center">
<div className="flex w-1/2 min-w-[280px] flex-col gap-8">
<Breadcrumbs title="Me"/>
<div className="flex justify-between">
<div className="flex items-center gap-4">
<Avatar className="h-28 w-28">
Expand Down
115 changes: 115 additions & 0 deletions components/ui/breadcrumbs-components.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { ChevronRight, MoreHorizontal } from "lucide-react"

import { cn } from "@lib/utils";

const Breadcrumb = React.forwardRef<
HTMLElement,
React.ComponentPropsWithoutRef<"nav"> & {
separator?: React.ReactNode
}
>(({ ...props }, ref) => <nav ref={ref} aria-label="breadcrumb" {...props} />)
Breadcrumb.displayName = "Breadcrumb"

const BreadcrumbList = React.forwardRef<
HTMLOListElement,
React.ComponentPropsWithoutRef<"ol">
>(({ className, ...props }, ref) => (
<ol
ref={ref}
className={cn(
"flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-1.5",
className
)}
{...props}
/>
))
BreadcrumbList.displayName = "BreadcrumbList"

const BreadcrumbItem = React.forwardRef<
HTMLLIElement,
React.ComponentPropsWithoutRef<"li">
>(({ className, ...props }, ref) => (
<li
ref={ref}
className={cn("inline-flex items-center gap-1.5", className)}
{...props}
/>
))
BreadcrumbItem.displayName = "BreadcrumbItem"

const BreadcrumbLink = React.forwardRef<
HTMLAnchorElement,
React.ComponentPropsWithoutRef<"a"> & {
asChild?: boolean
}
>(({ asChild, className, ...props }, ref) => {
const Comp = asChild ? Slot : "a"

return (
<Comp
ref={ref}
className={cn("transition-colors hover:text-foreground", className)}
{...props}
/>
)
})
BreadcrumbLink.displayName = "BreadcrumbLink"

const BreadcrumbPage = React.forwardRef<
HTMLSpanElement,
React.ComponentPropsWithoutRef<"span">
>(({ className, ...props }, ref) => (
<span
ref={ref}
role="link"
aria-disabled="true"
aria-current="page"
className={cn("font-normal text-foreground", className)}
{...props}
/>
))
BreadcrumbPage.displayName = "BreadcrumbPage"

const BreadcrumbSeparator = ({
children,
className,
...props
}: React.ComponentProps<"li">) => (
<li
role="presentation"
aria-hidden="true"
className={cn("[&>svg]:size-2.5", className)}
{...props}
>
{children ?? <ChevronRight size={20} />}
</li>
)
BreadcrumbSeparator.displayName = "BreadcrumbSeparator"

const BreadcrumbEllipsis = ({
className,
...props
}: React.ComponentProps<"span">) => (
<span
role="presentation"
aria-hidden="true"
className={cn("flex h-9 w-9 items-center justify-center", className)}
{...props}
>
<MoreHorizontal className="h-4 w-4" />
<span className="sr-only">More</span>
</span>
)
BreadcrumbEllipsis.displayName = "BreadcrumbElipssis"

export {
Breadcrumb,
BreadcrumbList,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbPage,
BreadcrumbSeparator,
BreadcrumbEllipsis,
}
Loading

0 comments on commit c8f48f6

Please sign in to comment.