Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add a footer visible to authenticated users #388

Merged
merged 7 commits into from
Jul 14, 2024
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: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-switch": "^1.1.0",
"@radix-ui/react-tabs": "^1.1.0",
"@radix-ui/react-toggle": "^1.1.0",
"@radix-ui/react-toggle-group": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.2",
"@tanstack/match-sorter-utils": "^8.15.1",
"@tanstack/query-broadcast-client-experimental": "^5.49.1",
Expand Down
58 changes: 58 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 44 additions & 0 deletions src/components/ui/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import {
} from "lucide-react";

export type LucideIcon = LucideIconType;
interface SvgProps extends React.SVGProps<SVGSVGElement> {}

export const icons = {
Dot: DotIcon,
Expand Down Expand Up @@ -125,4 +126,47 @@ export const icons = {
User: User2Icon,
Users: Users2Icon,
AltMaximize: Maximize2Icon,
Twitter: (props: SvgProps) => {
return (
<svg
stroke-linejoin="round"
viewBox="0 0 16 16"
aria-label="Twitter"
style={{ color: "currentcolor" }}
{...props}
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M0.5 0.5H5.75L9.48421 5.71053L14 0.5H16L10.3895 6.97368L16.5 15.5H11.25L7.51579 10.2895L3 15.5H1L6.61053 9.02632L0.5 0.5ZM12.0204 14L3.42043 2H4.97957L13.5796 14H12.0204Z"
fill="currentColor"
></path>
</svg>
);
},
GitHub: (props: SvgProps) => {
return (
<svg
stroke-linejoin="round"
viewBox="0 0 16 16"
aria-label="GitHub"
style={{ color: "currentcolor" }}
{...props}
>
<g clip-path="url(#clip0_872_3147)">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M8 0C3.58 0 0 3.57879 0 7.99729C0 11.5361 2.29 14.5251 5.47 15.5847C5.87 15.6547 6.02 15.4148 6.02 15.2049C6.02 15.0149 6.01 14.3851 6.01 13.7154C4 14.0852 3.48 13.2255 3.32 12.7757C3.23 12.5458 2.84 11.836 2.5 11.6461C2.22 11.4961 1.82 11.1262 2.49 11.1162C3.12 11.1062 3.57 11.696 3.72 11.936C4.44 13.1455 5.59 12.8057 6.05 12.5957C6.12 12.0759 6.33 11.726 6.56 11.5261C4.78 11.3262 2.92 10.6364 2.92 7.57743C2.92 6.70773 3.23 5.98797 3.74 5.42816C3.66 5.22823 3.38 4.40851 3.82 3.30888C3.82 3.30888 4.49 3.09895 6.02 4.1286C6.66 3.94866 7.34 3.85869 8.02 3.85869C8.7 3.85869 9.38 3.94866 10.02 4.1286C11.55 3.08895 12.22 3.30888 12.22 3.30888C12.66 4.40851 12.38 5.22823 12.3 5.42816C12.81 5.98797 13.12 6.69773 13.12 7.57743C13.12 10.6464 11.25 11.3262 9.47 11.5261C9.76 11.776 10.01 12.2558 10.01 13.0056C10.01 14.0752 10 14.9349 10 15.2049C10 15.4148 10.15 15.6647 10.55 15.5847C12.1381 15.0488 13.5182 14.0284 14.4958 12.6673C15.4735 11.3062 15.9996 9.67293 16 7.99729C16 3.57879 12.42 0 8 0Z"
fill="currentColor"
></path>
</g>
<defs>
<clipPath id="clip0_872_3147">
<rect width="16" height="16" fill="white"></rect>
</clipPath>
</defs>
</svg>
);
},
} as const;
60 changes: 60 additions & 0 deletions src/components/ui/toggle-group.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import * as React from "react";
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
import { VariantProps } from "class-variance-authority";

import { toggleVariants } from "@/components/ui/toggle";

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

const ToggleGroupContext = React.createContext<
VariantProps<typeof toggleVariants>
>({
size: "default",
variant: "default",
});

const ToggleGroup = React.forwardRef<
React.ElementRef<typeof ToggleGroupPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root> &
VariantProps<typeof toggleVariants>
>(({ className, variant, size, children, ...props }, ref) => (
<ToggleGroupPrimitive.Root
ref={ref}
className={cn("flex items-center justify-center gap-1", className)}
{...props}
>
<ToggleGroupContext.Provider value={{ variant, size }}>
{children}
</ToggleGroupContext.Provider>
</ToggleGroupPrimitive.Root>
));

ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;

const ToggleGroupItem = React.forwardRef<
React.ElementRef<typeof ToggleGroupPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> &
VariantProps<typeof toggleVariants>
>(({ className, children, variant, size, ...props }, ref) => {
const context = React.useContext(ToggleGroupContext);

return (
<ToggleGroupPrimitive.Item
ref={ref}
className={cn(
toggleVariants({
variant: context.variant || variant,
size: context.size || size,
}),
className
)}
{...props}
>
{children}
</ToggleGroupPrimitive.Item>
);
});

ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;

export { ToggleGroup, ToggleGroupItem };
43 changes: 43 additions & 0 deletions src/components/ui/toggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as React from "react";
import * as TogglePrimitive from "@radix-ui/react-toggle";
import { cva, type VariantProps } from "class-variance-authority";

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

const toggleVariants = cva(
"inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground",
{
variants: {
variant: {
default: "bg-transparent",
outline:
"border border-input bg-transparent hover:bg-accent hover:text-accent-foreground",
},
size: {
default: "h-10 px-3",
sm: "h-9 px-2.5",
lg: "h-11 px-5",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
);

const Toggle = React.forwardRef<
React.ElementRef<typeof TogglePrimitive.Root>,
React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root> &
VariantProps<typeof toggleVariants>
>(({ className, variant, size, ...props }, ref) => (
<TogglePrimitive.Root
ref={ref}
className={cn(toggleVariants({ variant, size, className }))}
{...props}
/>
));

Toggle.displayName = TogglePrimitive.Root.displayName;

export { Toggle, toggleVariants };
147 changes: 147 additions & 0 deletions src/routes/-components/auth/footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import * as React from "react";
import { Link } from "@tanstack/react-router";

import { Button } from "@/components/ui/button";
import { icons } from "@/components/ui/icons";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";

import { useTernaryDarkMode } from "@/lib/hooks/useTernaryDarkMode";
import { useGlobalDialogContext } from "@/lib/context/modals";

import { UI_APPLICATION_NAME } from "@/lib/utils/constants";

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

export default function AuthFooter() {
const { ternaryDarkMode, setTernaryDarkMode } = useTernaryDarkMode();
const { setShowCommandMenu } = useGlobalDialogContext();

return (
<footer className="border-t bg-card px-1 text-foreground/65 md:px-5">
<div className="mx-auto grid max-w-[1700px] gap-4 px-4 pb-6 pt-5 md:px-10">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<Link
to="/"
className="rounded ring-offset-background transition-colors focus-within:text-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
>
<img
// logo url is set in the global css under the name --logo-url
className="h-8 w-8 rounded-full p-1 opacity-65 [content:var(--logo-url)] focus-within:opacity-100 hover:opacity-100"
alt={UI_APPLICATION_NAME}
style={{ imageRendering: "crisp-edges" }}
/>
<span className="sr-only">Go to the home page</span>
</Link>
<p className="text-sm font-medium">
© {new Date().getFullYear()}
<span className="sr-only md:not-sr-only">
{" "}
{UI_APPLICATION_NAME}. All rights reserved.
</span>
</p>
</div>
<div className="flex items-center gap-2">
<div className="hidden md:block">
<Button
variant="ghost"
size="sm"
className="gap-2 tracking-tight"
onClick={() => {
setShowCommandMenu(true);
}}
>
<span>Command menu</span>
<div className="inline-flex items-center gap-1">
<span
className="rounded border bg-background px-1 py-0.5"
aria-hidden
>
{IsMacLike ? "⌘" : "Ctrl"}
</span>
<span aria-hidden>+</span>
<span
className="rounded border bg-background px-1.5 py-0.5"
aria-hidden
>
K
</span>
<span className="sr-only">
{IsMacLike ? "⌘" : "Ctrl"} + K
</span>
</div>
</Button>
</div>
<div>
<ToggleGroup
type="single"
size="sm"
className="gap-0.5 rounded-2xl border p-0.5"
value={ternaryDarkMode}
onValueChange={(value) => {
switch (value) {
case "system":
setTernaryDarkMode("system");
break;
case "light":
setTernaryDarkMode("light");
break;
case "dark":
setTernaryDarkMode("dark");
break;
default:
console.warn(
"Unhandled theme value in the footer switcher:",
value
);
break;
}
}}
>
<ToggleGroupItem
className="h-8 rounded-2xl"
aria-label="Set theme to system"
value="system"
>
<icons.System className="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem
className="h-8 rounded-2xl"
aria-label="Set theme to light"
value="light"
>
<icons.Sun className="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem
className="h-8 rounded-2xl"
aria-label="Set theme to dark"
value="dark"
>
<icons.Moon className="h-4 w-4" />
</ToggleGroupItem>
</ToggleGroup>
</div>
</div>
</div>
<div>
<div className="flex items-center gap-2">
<a
className="inline-flex h-8 items-center rounded p-2 ring-offset-background transition-colors focus-within:text-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
href="https://github.com/seancassiere/nv-rental-clone"
target="_blank"
>
<icons.GitHub className="h-4 w-4" />
</a>
<a
className="inline-flex h-8 items-center rounded p-2 ring-offset-background transition-colors focus-within:text-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
href="https://x.com/seancassiere"
target="_blank"
>
<icons.Twitter className="h-3 w-3" />
</a>
</div>
</div>
</div>
</footer>
);
}
Loading