Skip to content

Commit

Permalink
feat: pad out icons folder with even more reusable icons
Browse files Browse the repository at this point in the history
also hide the later parts of module sign in reaons
  • Loading branch information
Gobot1234 committed Apr 20, 2024
1 parent c5911c2 commit c75db8f
Show file tree
Hide file tree
Showing 12 changed files with 163 additions and 88 deletions.
46 changes: 46 additions & 0 deletions apps/forge/src/components/icons/Locations.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Location as LocationType } from "@ignis/types/training";
import { Heart, ParkingMeter, Wrench } from "lucide-react";
import React from "react";
import { IconWithTooltip } from ".";

interface IconProps {
className?: string;
}

export const Mainspace: React.FC<IconProps> = (props) => (
<IconWithTooltip {...props} IconComponent={Wrench} tooltipText="Mainspace" strokeClass="stroke-mainspace" />
);

export const Heartspace: React.FC<IconProps> = (props) => (
<IconWithTooltip {...props} IconComponent={Heart} tooltipText="Heartspace" strokeClass="stroke-heartspace" />
);

export const GeorgePorter: React.FC<IconProps> = (props) => (
<IconWithTooltip
{...props}
IconComponent={ParkingMeter}
tooltipText="George Porter"
strokeClass="stroke-george-porter"
/>
);

export const Location: React.FC<IconProps & { location: Uppercase<LocationType> | Lowercase<LocationType> }> = ({
location,
className,
}) => {
switch (location.toLowerCase() as Lowercase<LocationType>) {
case "mainspace":
return <MainspaceIcon className={className} />;
case "heartspace":
return <HeartspaceIcon className={className} />;
case "george_porter":
return <GeorgePorterIcon className={className} />;
default:
throw new Error("unreachable");
}
};

export const MainspaceIcon = Mainspace;
export const HeartspaceIcon = Heartspace;
export const GeorgePorterIcon = GeorgePorter;
export const LocationIcon = Location;
24 changes: 24 additions & 0 deletions apps/forge/src/components/icons/SignInReason.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ReasonCategory } from "@ignis/types/sign_in";
import { Bot, Crown, GraduationCap, LucideIcon, PartyPopper, Rocket, UserRound } from "lucide-react";

export const Category = ({ category, ...props }: { category: ReasonCategory } & React.ComponentProps<LucideIcon>) => {
switch (category) {
case "UNIVERSITY_MODULE":
return <GraduationCap {...props} />;
case "PERSONAL_PROJECT":
return <UserRound {...props} />;
case "SOCIETY":
// ROBOTEERS PLUG WOOO
return <Bot {...props} />;
case "REP_SIGN_IN":
return <Crown {...props} />;
case "CO_CURRICULAR_GROUP":
return <Rocket {...props} />;
case "EVENT":
return <PartyPopper {...props} />;
default:
throw new Error("unreachable");
}
};

export const CategoryIcon = Category;
53 changes: 53 additions & 0 deletions apps/forge/src/components/icons/Team.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { removeSuffix } from "@/lib/utils";
import {
BarChart4,
Box,
CalendarIcon,
Cog,
Computer,
Construction,
Diamond,
Hammer,
HardHat,
LucideIcon,
Megaphone,
Puzzle,
Send,
Users,
} from "lucide-react";
import * as React from "react";

export default function Team({ team, ...props }: { team: string } & React.ComponentProps<LucideIcon>) {
switch (removeSuffix(team, "Team").trim()) {
case "IT":
return <Computer {...props} />;
case "3DP":
return <Box {...props} />;
case "Hardware":
return <Hammer {...props} />;
case "Publicity":
return <Megaphone {...props} />;
case "Events":
return <CalendarIcon {...props} />;
case "Relations":
return <Send {...props} />;
case "Operations":
return <Cog />;
case "Recruitment & Development":
return <BarChart4 {...props} />; // stonks?
case "Health & Safety":
return <HardHat {...props} />;
case "Inclusions":
return <Users {...props} />;
case "Unsorted Reps":
return <Puzzle {...props} />;
case "Future Reps":
return <Construction {...props} />;
case "Staff":
return <Diamond {...props} />;
default:
throw new Error("Sorry your team has been forgotten about... cry harder");
}
}

export const TeamIcon = Team;
39 changes: 0 additions & 39 deletions apps/forge/src/components/icons/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
import { cn } from "@/lib/utils";
import { Location } from "@ignis/types/training";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@ui/components/ui/tooltip";
import { Heart, ParkingMeter, Wrench } from "lucide-react";
import React from "react";

interface IconProps {
className?: string;
}

interface IconWithTooltip {
className?: string;
IconComponent: React.ComponentType<any>;
Expand All @@ -29,36 +23,3 @@ export const IconWithTooltip: React.FC<IconWithTooltip> = ({ className, IconComp
</TooltipProvider>
);
};

export const MainspaceIcon: React.FC<IconProps> = (props) => (
<IconWithTooltip {...props} IconComponent={Wrench} tooltipText="Mainspace" strokeClass="stroke-mainspace" />
);

export const HeartspaceIcon: React.FC<IconProps> = (props) => (
<IconWithTooltip {...props} IconComponent={Heart} tooltipText="Heartspace" strokeClass="stroke-heartspace" />
);

export const GeorgePorterIcon: React.FC<IconProps> = (props) => (
<IconWithTooltip
{...props}
IconComponent={ParkingMeter}
tooltipText="George Porter"
strokeClass="stroke-george-porter"
/>
);

export const LocationIcon: React.FC<IconProps & { location: Uppercase<Location> | Lowercase<Location> }> = ({
location,
className,
}) => {
switch (location.toLowerCase() as Lowercase<Location>) {
case "mainspace":
return <MainspaceIcon className={className} />;
case "heartspace":
return <HeartspaceIcon className={className} />;
case "george_porter":
return <GeorgePorterIcon className={className} />;
default:
throw new Error("unreachable");
}
};
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import { ErrorDisplayProps, errorDisplay } from "@/components/errors/ErrorDisplay";
import { Category } from "@/components/icons/SignInReason";
import { FlowStepComponent } from "@/components/signin/actions/SignInManager/types";
import { signinActions } from "@/redux/signin.slice.ts";
import { AppDispatch, AppRootState } from "@/redux/store";
import { useSignInReasons } from "@/services/signin/signInReasonService";
import type { Reason, ReasonCategory } from "@ignis/types/sign_in";
import type { Reason } from "@ignis/types/sign_in";
import { Button } from "@ui/components/ui/button";
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@ui/components/ui/card";
import { Input } from "@ui/components/ui/input";
import { Loader } from "@ui/components/ui/loader";
import Fuse from "fuse.js";
import { Bot, Crown, GraduationCap, HelpCircle, PartyPopper, Rocket, UserRound } from "lucide-react";
import memoizeOne from "memoize-one";
import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { errorDisplay, ErrorDisplayProps } from "@/components/errors/ErrorDisplay";

const SignInReasonInput: FlowStepComponent = ({ onSecondary, onPrimary }) => {
const [inputValue, setInputValue] = useState<string>("");
Expand Down Expand Up @@ -42,7 +41,7 @@ const SignInReasonInput: FlowStepComponent = ({ onSecondary, onPrimary }) => {
}),
);
}
}, [hasSessionError, signInReasons]);
}, [hasSessionError, signInReasons, selectedReason]);

const handleSelectReason = (reason: Reason): void => {
setInputValue(""); // Clear input value after selecting a reason
Expand Down Expand Up @@ -91,26 +90,6 @@ const SignInReasonInput: FlowStepComponent = ({ onSecondary, onPrimary }) => {
}
};

const iconForCategory = memoizeOne((category: ReasonCategory) => {
switch (category) {
case "UNIVERSITY_MODULE":
return <GraduationCap className="mr-1" />;
case "PERSONAL_PROJECT":
return <UserRound className="mr-1" />;
case "SOCIETY":
// ROBOTEERS PLUG WOOO
return <Bot className="mr-1" />;
case "REP_SIGN_IN":
return <Crown className="mr-1" />;
case "CO_CURRICULAR_GROUP":
return <Rocket className="mr-1" />;
case "EVENT":
return <PartyPopper className="mr-1" />;
default:
return <HelpCircle className="mr-1" />;
}
});

const filteredReasons = inputValue ? fuse.search(inputValue, { limit: 20 }) : [];

useEffect(() => {
Expand Down Expand Up @@ -169,7 +148,7 @@ const SignInReasonInput: FlowStepComponent = ({ onSecondary, onPrimary }) => {
className={`cursor-pointer p-2 ${index === highlightedIndex ? "bg-accent" : "hover:bg-accent"}`}
>
<div className="flex">
{iconForCategory(result.item.category)}
{<Category category={result.item.category} className="mr-1" />}
{result.item.name}
</div>
</li>
Expand Down Expand Up @@ -199,9 +178,9 @@ const SignInReasonInput: FlowStepComponent = ({ onSecondary, onPrimary }) => {
{selectedReason && (
<div className="mt-2 p-2 border border-gray-200 dark:border-gray-700 bg-card text-card-foreground">
<p className="flex">
Selected Reason:{" "}
<strong className="flex">
{iconForCategory(selectedReason.category)} {selectedReason.name}
Selected Reason:
<strong className="flex ml-1">
{<Category category={selectedReason.category} className="mr-1" />} {selectedReason.name}
</strong>
</p>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ const ToolSelectionInput: FlowStepComponent = ({ onSecondary, onPrimary }) => {
title="Un-acquired Training"
trainings={trainingMap.DISABLED}
toolTipContent="Tools the user aren't trained to use"
/>{" "}
/>
</CollapsibleContent>
</>
</Collapsible>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LocationIcon } from "@/components/icons";
import { LocationIcon } from "@/components/icons/Locations";
import { SignInStat } from "@ignis/types/users";
import { Datum, ResponsiveCalendar } from "@nivo/calendar";
import { useNavigate } from "@tanstack/react-router";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Category } from "@/components/icons/SignInReason";
import { PartialReason } from "@ignis/types/sign_in.ts";
import { Badge } from "@ui/components/ui/badge.tsx";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@ui/components/ui/tooltip";

interface SignInReasonDisplayProps {
tools: string[];
Expand All @@ -15,9 +17,19 @@ export const SignInReasonDisplay: React.FC<SignInReasonDisplayProps> = ({ tools,
Sign In Reason
</div>
<div className="text-center font-mono mt-2 justify-center">
<Badge variant="default" className="max-w-48 rounded-sm shadow-lg">
{reason.name}
</Badge>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Badge variant="default" className="max-w-48 rounded-sm shadow-lg">
<div className="flex">
{<Category category={reason.category} className="mr-1" />}
{reason.category === "UNIVERSITY_MODULE" ? reason.name.split(" ")[0] : reason.name}
</div>
</Badge>
</TooltipTrigger>
<TooltipContent>{reason.name}</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
</div>
<div className="border-gray-500 p-2 rounded-sm mb-4">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import * as React from "react";
import { useQuery } from "@tanstack/react-query";
import TeamIcon from "@/components/icons/Team";
import { ManageUserWidgetProps } from "@/components/signin/dashboard/components/SignedInUserCard/ManageUserWidget.tsx";
import { getTeams } from "@/services/users/getTeams.ts";
import MultiSelectFormField from "@ui/components/ui/multi-select.tsx";
import { Loader } from "@ui/components/ui/loader.tsx";
import { toast } from "sonner";
import promoteToRep from "@/services/users/promoteToRep.ts";
import { zodResolver } from "@hookform/resolvers/zod";
import { ShortTeam } from "@ignis/types/users.ts";
import { useQuery } from "@tanstack/react-query";
import { Button } from "@ui/components/ui/button.tsx";
import {
Form,
Expand All @@ -15,12 +15,12 @@ import {
FormLabel,
FormMessage,
} from "@ui/components/ui/form.tsx";
import { Loader } from "@ui/components/ui/loader.tsx";
import MultiSelectFormField from "@ui/components/ui/multi-select.tsx";
import * as React from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { toast } from "sonner";
import { z } from "zod";
import { ShortTeam } from "@ignis/types/users.ts";
import TeamIcon from "@/components/signin/dashboard/components/TeamIcon.tsx";
import promoteToRep from "@/services/users/promoteToRep.ts";

const FormSchema = z.object({
teams: z.array(z.string()).min(1).nonempty("Please select at least one team."),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { UserAvatar } from "@/components/avatar";
import { TeamIcon } from "@/components/icons/Team";
import { AdminDisplay } from "@/components/signin/dashboard/components/SignedInUserCard/AdminDisplay.tsx";
import { ManageUserWidget } from "@/components/signin/dashboard/components/SignedInUserCard/ManageUserWidget.tsx";
import { SignInReasonDisplay } from "@/components/signin/dashboard/components/SignedInUserCard/SignInReasonDisplay.tsx";
import TeamIcon from "@/components/signin/dashboard/components/TeamIcon.tsx";
import { TimeDisplay } from "@/components/signin/dashboard/components/SignedInUserCard/TimeDisplay.tsx";
import { iForgeEpoch } from "@/config/constants.ts";
import { REP_OFF_SHIFT, REP_ON_SHIFT } from "@/lib/constants.ts";
import { AppRootState } from "@/redux/store.ts";
import { PostSignOut, PostSignOutProps } from "@/services/signin/signInService.ts";
Expand All @@ -18,9 +21,6 @@ import { LogOut, Plus } from "lucide-react";
import * as React from "react";
import { useSelector } from "react-redux";
import { toast } from "sonner";
import { AdminDisplay } from "@/components/signin/dashboard/components/SignedInUserCard/AdminDisplay.tsx";
import { TimeDisplay } from "@/components/signin/dashboard/components/SignedInUserCard/TimeDisplay.tsx";
import { iForgeEpoch } from "@/config/constants.ts";

interface SignInUserCardProps {
user: PartialUserWithTeams;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,6 @@ export default function TeamIcon({ team, ...props }: { team: string } & React.Co
case "Staff":
return <Diamond {...props} />;
default:
throw new Error("Sorry your team has been forgotten... about cry harder");
throw new Error("Sorry your team has been forgotten about... cry harder");
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { UserAvatar } from "@/components/avatar";
import { LocationIcon } from "@/components/icons";
import { LocationIcon } from "@/components/icons/Locations";
import SignInsChart from "@/components/signin/dashboard/components/SignInsChart.tsx";
import Title from "@/components/title";
import { extractError } from "@/lib/utils";
Expand Down

0 comments on commit c75db8f

Please sign in to comment.