Skip to content

Commit

Permalink
feat: nicer common reasons
Browse files Browse the repository at this point in the history
  • Loading branch information
Gobot1234 committed Oct 30, 2024
1 parent 2cc25fb commit de57439
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 56 deletions.
5 changes: 3 additions & 2 deletions apps/anvil/src/sign-in/sign-in.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
ParseIntPipe,
Patch,
Post,
Query,
Req,
UseGuards,
UseInterceptors,
Expand Down Expand Up @@ -177,7 +178,7 @@ export class SignInController {

@Get("/common-reasons")
@IsRep()
async getPopularSignInReasons(@Param("location") location: LocationName) {
return this.signInService.getPopularReasons(location);
async getPopularSignInReasons(@Param("location") location: LocationName, @Query("rep") rep: string) {
return this.signInService.getPopularReasons(location, rep === "true");
}
}
65 changes: 22 additions & 43 deletions apps/anvil/src/sign-in/sign-in.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -811,41 +811,26 @@ export class SignInService implements OnModuleInit {
);
}

async getPopularReasons(name: LocationName) {
return await this.dbService.query(
e.select(
e.op(
e.select(
e.group(
e.select(e.sign_in.SignIn, (sign_in) => ({
filter: e.all(
e.set(
e.op(sign_in.location.name, "=", e.cast(e.sign_in.LocationName, name)),
e.op(sign_in.reason.name, "in", e.set(REP_ON_SHIFT, REP_OFF_SHIFT, PERSONAL)),
),
),
})),
(sign_in) => ({
by: { reason: sign_in.reason },
}),
async getPopularReasons(name: LocationName, rep: boolean) {
return await this.dbService
.query(
e.select({
default_: e.select(e.sign_in.Reason, (reason) => ({
filter: e.op(reason.name, "in", e.set(...(rep ? [REP_ON_SHIFT, REP_OFF_SHIFT] : []), PERSONAL)),
order_by: e.op(
// Personal then on then off
0,
"if",
e.op(e.assert_single(reason.name), "=", PERSONAL),
"else",
e.op(1, "if", e.op(e.assert_single(reason.name), "=", REP_ON_SHIFT), "else", 2),
),
(group) => ({
name: e.assert_single(group.elements.reason.name),
category: e.assert_single(group.elements.reason.category),
id_: e.assert_single(group.elements.reason.id),
count: e.count(group.elements),
order_by: e.op(
// Personal then on then off
0,
"if",
e.op(group.elements.reason.name, "=", PERSONAL),
"else",
e.op(1, "if", e.op(group.elements.reason.name, "=", REP_ON_SHIFT), "else", 2),
),
}),
),
"intersect",
e.select(
id_: reason.id,
name: true,
category: true,
count: e.select(0),
})),
common: e.select(
e.group(
e.select(e.sign_in.SignIn, (sign_in) => ({
filter: e.all(
Expand All @@ -869,17 +854,11 @@ export class SignInService implements OnModuleInit {
expression: e.count(group.elements),
direction: e.DESC,
},
limit: 3,
limit: rep ? 3 : 5,
}),
),
),
(reason) => ({
name: e.assert_exists(reason.name),
category: e.assert_exists(reason.category),
id: e.assert_exists(reason.id_),
count: reason.count,
}),
),
);
)
.then(({ common, default_ }) => [...default_, ...common].map((reason) => ({ id: reason.id_, ...reason })));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@ import { Category } from "@/components/icons/SignInReason.tsx";
import { cn } from "@/lib/utils.ts";
import { PartialReason } from "@ignis/types/sign_in.ts";
import { Badge } from "@ui/components/ui/badge.tsx";
import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from "@ui/components/ui/tooltip.tsx";
import { Kbd } from "@ui/components/ui/kbd";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@ui/components/ui/tooltip.tsx";

export const SignInReason = ({ reason, className }: { reason: PartialReason; className?: string }) => {
export const SignInReason = ({
reason,
index,
className,
}: { reason: PartialReason; index?: number; className?: string }) => {
return (
<TooltipProvider>
<Tooltip>
Expand All @@ -14,6 +19,7 @@ export const SignInReason = ({ reason, className }: { reason: PartialReason; cla
variant="default"
className={cn("max-w-48 rounded-sm shadow-lg justify-center items-center", className)}
>
{index !== undefined ? <Kbd className="mr-1 text-muted-foreground text-center">F{index + 1}</Kbd> : null}
{<Category category={reason.category} className="mr-1" />}
{reason.category === "UNIVERSITY_MODULE" ? reason.name.split(" ")[0] : reason.name}
</Badge>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,10 @@ export const SignInReasonInput: FlowStepComponent = ({ onSecondary, onPrimary })
}
} else if (event.key === "Escape") {
handleClearReason();
} else if (event.key >= "1" && event.key <= "8") {
const index = Number.parseInt(event.key) - 1;
} else if (event.key >= "F1" && event.key <= "F6") {
const index = Number.parseInt(event.key.slice(1)) - 1;
if (commonReasons && index < commonReasons.length) {
event.preventDefault(); // Prevent default F-key behavior
handleSelectReason(commonReasons[index]);
}
}
Expand Down Expand Up @@ -128,20 +129,19 @@ export const SignInReasonInput: FlowStepComponent = ({ onSecondary, onPrimary })
<CardHeader>
<CardTitle>Sign-In Reason Input</CardTitle>
<CardDescription>Start typing to match your sign-in reason or pick a recent common reason:</CardDescription>
{/* {commonReasonsError ? ( // FIXME
{commonReasonsError ? ( // FIXME
`Failed to fetch common reasons: ${extractError(commonReasonsError)}`
) : commonReasonsIsLoading ? (
<Loader />
) : (
<div className="flex flex-wrap">
{commonReasons?.map((reason, index) => (
<div key={reason.id} onClick={() => handleSelectReason(reason)} className="flex hover:cursor-pointer m-1">
<span className="mr-1 text-muted-foreground">{index + 1}</span>
<SignInReason reason={reason} />
<SignInReason reason={reason} index={index} />
</div>
))}
</div>
)} */}
)}
</CardHeader>
<CardContent>
{isLoading && <Loader />}
Expand All @@ -155,7 +155,7 @@ export const SignInReasonInput: FlowStepComponent = ({ onSecondary, onPrimary })
value={inputValue}
onChange={handleInputChange}
onKeyDown={handleKeyDown}
placeholder="Start typing a reason or press 1-8 for quick selection..."
placeholder="Start typing a reason or press F1-F6 for quick selection..."
className="mb-2"
/>
{inputValue && (
Expand Down
6 changes: 4 additions & 2 deletions apps/forge/src/services/sign_in/signInReasonService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ export const fetchSignInReasons = async (): Promise<Reason[]> => {
return response.data;
};

export const getCommonReasons = async (location: LocationName): Promise<PartialReason[]> => {
const { data } = await axiosInstance.get(`/location/${location}/common-reasons`);
export const getCommonReasons = async (location: LocationName, rep?: boolean): Promise<PartialReason[]> => {
const { data } = await axiosInstance.get(`/location/${location}/common-reasons`, {
params: { rep: rep ? "true" : "" },
});
return data;
};

Expand Down
18 changes: 18 additions & 0 deletions packages/ui/components/ui/kbd.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { cn } from "@/lib/utils";
import React from "react";

export const Kbd = ({
children,
className,
...props
}: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>) => (
<div
className={cn(
"rounded-sm border border-border bg-muted px-1.5 py-0.5 font-mono text-sm shadow-[rgba(255,_255,_255,_0.1)_0px_0.5px_0px_0px_inset,_rgb(248,_249,_250)_0px_1px_5px_0px_inset,_rgb(193,_200,_205)_0px_0px_0px_0.5px,_rgb(193,_200,_205)_0px_2px_1px_-1px,_rgb(193,_200,_205)_0px_1px_0px_0px] dark:shadow-[rgba(255,_255,_255,_0.1)_0px_0.5px_0px_0px_inset,_rgb(26,_29,_30)_0px_1px_5px_0px_inset,_rgb(76,_81,_85)_0px_0px_0px_0.5px,_rgb(76,_81,_85)_0px_2px_1px_-1px,_rgb(76,_81,_85)_0px_1px_0px_0px]",
className,
)}
{...props}
>
<kbd>{children}</kbd>
</div>
);

0 comments on commit de57439

Please sign in to comment.