Skip to content

Commit

Permalink
feat(web): add new dashboard (#89)
Browse files Browse the repository at this point in the history
  • Loading branch information
cstrnt authored Oct 30, 2023
1 parent 19d301e commit 76c4f89
Show file tree
Hide file tree
Showing 63 changed files with 1,868 additions and 791 deletions.
16 changes: 16 additions & 0 deletions apps/web/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "tailwind.config.cjs",
"css": "src/styles/shadcn.css",
"baseColor": "slate",
"cssVariables": true
},
"aliases": {
"utils": "lib/utils",
"components": "components"
}
}
13 changes: 9 additions & 4 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,16 @@
"@planetscale/database": "^1.11.0",
"@prisma/adapter-planetscale": "5.4.2",
"@prisma/client": "5.4.2",
"@radix-ui/react-avatar": "^1.0.2",
"@radix-ui/react-avatar": "^1.0.3",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.4",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-navigation-menu": "^1.1.3",
"@radix-ui/react-popover": "^1.0.5",
"@radix-ui/react-popover": "^1.0.6",
"@radix-ui/react-radio-group": "^1.1.3",
"@radix-ui/react-select": "^1.2.2",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-switch": "^1.0.2",
"@radix-ui/react-tooltip": "^1.0.5",
"@react-email/button": "0.0.5",
Expand Down Expand Up @@ -70,6 +74,7 @@
"chart.js": "^4.2.1",
"class-variance-authority": "^0.4.0",
"clsx": "^1.2.1",
"cmdk": "^0.2.0",
"csstype": "^3.1.2",
"dayjs": "^1.11.7",
"framer-motion": "^10.12.7",
Expand Down Expand Up @@ -100,8 +105,8 @@
"shiki": "^0.11.1",
"stripe": "^11.18.0",
"superjson": "1.9.1",
"tailwind-merge": "^1.12.0",
"tailwindcss-animate": "^1.0.5",
"tailwind-merge": "^1.13.1",
"tailwindcss-animate": "^1.0.6",
"ts-pattern": "^4.2.2",
"zod": "^3.21.4",
"zustand": "^4.4.1"
Expand Down
13 changes: 4 additions & 9 deletions apps/web/src/components/AddFeatureFlagModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { RadioSelect } from "./RadioSelect";
import { Toggle } from "./Toggle";

import { useTracking } from "lib/tracking";
import { Input } from "./ui/input";

type Props = {
onClose: () => void;
Expand Down Expand Up @@ -42,8 +43,6 @@ export function ChangeFlagForm({
isRemoteConfig?: boolean;
}) {
const inputRef = useRef<HTMLInputElement>(null);
const inputClassName =
"form-input w-full rounded-md border border-gray-500 bg-gray-600 px-4 py-2 text-white placeholder-gray-400 shadow-sm focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2";

const [state, setState] = useState<FlagFormValues>(initialValues);

Expand Down Expand Up @@ -71,13 +70,12 @@ export function ChangeFlagForm({
<div className="flex flex-col space-y-5">
<div>
<label className="mb-1 block text-pink-50">Name</label>
<input
<Input
ref={inputRef}
type="text"
defaultValue={initialValues.name}
onChange={(e) => onChange({ name: e.target.value })}
placeholder={isRemoteConfig ? "My Remote Config" : "My Feature Flag"}
className={inputClassName}
/>
{errors.name && (
<p className="mt-1 text-sm text-red-500">{errors.name}</p>
Expand Down Expand Up @@ -129,18 +127,17 @@ export function ChangeFlagForm({
/>
)}
{state.type === "STRING" && (
<input
<Input
type="text"
value={state.value}
onChange={(e) => onChange({ value: e.target.value })}
placeholder={
isRemoteConfig ? "My Remote Config" : "My Feature Flag"
}
className="form-input w-full rounded-md border border-gray-500 bg-gray-600 px-4 py-2 text-white placeholder-gray-400 shadow-sm focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2"
/>
)}
{state.type === "NUMBER" && (
<input
<Input
type="number"
value={state.value}
onChange={(e) => onChange({ value: e.target.value })}
Expand All @@ -149,7 +146,6 @@ export function ChangeFlagForm({
["e", "E", "+", "-"].includes(e.key) && e.preventDefault();
}}
placeholder="123"
className="form-input w-full rounded-md border border-gray-500 bg-gray-600 px-4 py-2 text-white placeholder-gray-400 shadow-sm focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2"
/>
)}
{state.type === "JSON" && (
Expand Down Expand Up @@ -193,7 +189,6 @@ export const AddFeatureFlagModal = ({
isRemoteConfig ? "Create new remote config" : "Create new feature flag"
}
confirmText="Create"
initialFocusRef={inputRef}
size="full"
onConfirm={async () => {
const errors: Partial<FlagFormValues> = {};
Expand Down
7 changes: 5 additions & 2 deletions apps/web/src/components/CodeSnippetModalButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { useRouter } from "next/router";
import { useState } from "react";
import { BsCodeSlash } from "react-icons/bs";
import { CodeSnippet } from "./CodeSnippet";
import { IconButton } from "./IconButton";
import {
DropdownMenu,
DropdownMenuContent,
Expand All @@ -14,6 +13,7 @@ import { Code, Copy } from "lucide-react";
import { useProjectId } from "lib/hooks/useProjectId";
import { toast } from "react-hot-toast";
import { useTracking } from "lib/tracking";
import { Button } from "./ui/button";

function CodeSnippetModal({
isOpen,
Expand Down Expand Up @@ -56,12 +56,15 @@ export function CodeSnippetModalButton() {
return (
<DropdownMenu>
<DropdownMenuTrigger
asChild
// all other events are prevented by radix :(
onPointerDown={() => {
trackEvent("Dashboard Code Clicked");
}}
>
<IconButton as="div" icon={<BsCodeSlash />} title="" />
<Button size="icon" variant="secondary" title="">
<BsCodeSlash size={20} />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent side="bottom" align="end">
<DropdownMenuItem onClick={onCopyProjectId}>
Expand Down
5 changes: 2 additions & 3 deletions apps/web/src/components/CreateAPIKeyModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useRef, useState } from "react";
import { toast } from "react-hot-toast";
import { trpc } from "utils/trpc";
import { Modal } from "./Modal";
import { Input } from "./ui/input";

type Props = {
onClose: () => void;
Expand All @@ -29,7 +30,6 @@ export const CreateAPIKeyModal = ({ onClose, isOpen, projectId }: Props) => {
onClose={onClose}
title="Create new API Key"
confirmText="Create"
initialFocusRef={inputRef}
onConfirm={async () => {
if (!trimmedName) {
toast.error("Name is required");
Expand All @@ -50,13 +50,12 @@ export const CreateAPIKeyModal = ({ onClose, isOpen, projectId }: Props) => {
}}
>
<label className="mb-1 block text-pink-50">Name</label>
<input
<Input
ref={inputRef}
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Name of the Application"
className="form-input rounded-md border border-gray-500 bg-gray-600 px-4 py-2 text-white placeholder-gray-400 shadow-sm focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2"
/>
</Modal>
);
Expand Down
5 changes: 2 additions & 3 deletions apps/web/src/components/CreateEnvironmentModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { PlausibleEvents } from "types/plausible-events";
import { trpc } from "utils/trpc";
import { Modal } from "./Modal";
import { useTracking } from "lib/tracking";
import { Input } from "./ui/input";

type Props = {
onClose: () => void;
Expand Down Expand Up @@ -35,7 +36,6 @@ export const CreateEnvironmentModal = ({
onClose={onClose}
title="Create new Environment"
confirmText="Create"
initialFocusRef={inputRef}
onConfirm={async () => {
if (!trimmedName) {
toast.error("Name is required");
Expand All @@ -61,13 +61,12 @@ export const CreateEnvironmentModal = ({
}}
>
<label className="mb-1 block text-pink-50">Name</label>
<input
<Input
ref={inputRef}
value={name}
onChange={(e) => setName(e.target.value)}
type="text"
placeholder="production"
className="form-input rounded-md border border-gray-500 bg-gray-600 px-4 py-2 text-white placeholder-gray-400 shadow-sm focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2"
/>
</Modal>
);
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/components/CreateProjectModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { trpc } from "utils/trpc";
import { Modal } from "./Modal";
import { useSession } from "next-auth/react";
import { useTracking } from "lib/tracking";
import { Input } from "./ui/input";

type Props = {
onClose: () => void;
Expand Down Expand Up @@ -61,12 +62,11 @@ export const CreateProjectModal = ({ onClose }: Props) => {
confirmText="Create"
size="full"
>
<input
<Input
type="text"
placeholder="Project Name"
required
onChange={handleChange}
className="form-input rounded-md border border-gray-500 bg-gray-600 px-8 py-2 text-white placeholder-gray-400 shadow-sm focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2"
/>
{!isValidName && (
<div className="pt-4 text-red-600">
Expand Down
12 changes: 2 additions & 10 deletions apps/web/src/components/DashboardButton.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
import { ComponentPropsWithRef } from "react";
import { twMerge } from "tailwind-merge";
import { Button } from "./ui/button";

type Props = ComponentPropsWithRef<"button">;

export function DashboardButton({ className, ...props }: Props) {
return (
<button
className={twMerge(
"rounded-md bg-accent-background px-3 py-0.5 text-accent-foreground transition-colors duration-200 ease-in-out hover:bg-accent-background-hover disabled:opacity-60",
className
)}
{...props}
/>
);
return <Button {...props} />;
}
54 changes: 1 addition & 53 deletions apps/web/src/components/DashboardHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
import { Mail, Code, HelpCircle, Book, Video } from "lucide-react";
import { CodeSnippetModalButton } from "./CodeSnippetModalButton";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "./DropdownMenu";
import { IconButton } from "./IconButton";
import Link from "next/link";
import { DOCS_URL } from "@tryabby/core";
import { useTracking } from "lib/tracking";
import { FaDiscord } from "react-icons/fa";
import { DISCORD_INVITE_URL } from "./Footer";
import { CodeSnippetModalButton } from "./CodeSnippetModalButton";

type Props = {
title: string;
Expand All @@ -23,46 +11,6 @@ export function DashboardHeader({ title }: Props) {
<div className="mb-4 flex items-center justify-between">
<h1 className="text-3xl font-bold">{title}</h1>
<div className="flex space-x-2">
<DropdownMenu>
<DropdownMenuTrigger>
<IconButton
as="div"
// all other events are prevented by radix :(
onPointerDown={() => {
trackEvent("Dashboard Help Clicked");
}}
icon={<HelpCircle />}
title=""
/>
</DropdownMenuTrigger>
<DropdownMenuContent side="bottom" align="end">
<DropdownMenuItem disabled>Need help?</DropdownMenuItem>
<Link href={DOCS_URL}>
<DropdownMenuItem>
<Book className="mr-2 h-4 w-4" />
Documentation
</DropdownMenuItem>
</Link>
<Link href="mailto:[email protected]">
<DropdownMenuItem>
<Mail className="mr-2 h-4 w-4" />
Send a Mail
</DropdownMenuItem>
</Link>
<Link href="https://cal.com/tim-raderschad/abby-help">
<DropdownMenuItem>
<Video className="mr-2 h-4 w-4" />
Book a free Call
</DropdownMenuItem>
</Link>
<Link href={DISCORD_INVITE_URL}>
<DropdownMenuItem>
<FaDiscord className="mr-2 h-4 w-4" />
Join our Discord
</DropdownMenuItem>
</Link>
</DropdownMenuContent>
</DropdownMenu>
<CodeSnippetModalButton />
</div>
</div>
Expand Down
4 changes: 3 additions & 1 deletion apps/web/src/components/DashboardSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ export function DashboardSection({
className?: string;
}) {
return (
<section className={twMerge("rounded-xl bg-gray-800 px-6 py-3", className)}>
<section
className={twMerge("rounded-lg bg-secondary px-6 py-3", className)}
>
{children}
</section>
);
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/DevtoolsArrow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export function DevtoolsArrow() {
initial={{ opacity: 0, scale: 0.5 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.5 }}
className="flex items-center rounded-md bg-primary-background p-1 font-mono text-xl text-accent-background"
className="flex items-center rounded-md bg-ab_primary-background p-1 font-mono text-xl text-ab_accent-background"
style={{
zIndex: 9999,
position: "fixed",
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/Divider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export function Divider({ className }: { className?: string }) {
return (
<div
className={twMerge(
"mx-auto h-[2px] max-w-xs bg-accent-background",
"mx-auto h-[2px] max-w-xs bg-ab_accent-background",
className
)}
/>
Expand Down
Loading

2 comments on commit 76c4f89

@vercel
Copy link

@vercel vercel bot commented on 76c4f89 Oct 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 76c4f89 Oct 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.