Skip to content

Commit 8331fb9

Browse files
authored
Merge pull request #209 from Merit-Systems/json/app-settings
Update app settings pages
2 parents 0175040 + c18b855 commit 8331fb9

48 files changed

Lines changed: 1622 additions & 51 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

echo-control/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,10 @@
6767
"@trpc/react-query": "^11.4.4",
6868
"@trpc/server": "^11.4.4",
6969
"@types/mdx": "^2.0.13",
70+
"@vercel/analytics": "^1.5.0",
7071
"@vercel/blob": "^0.25.1",
7172
"@vercel/otel": "^1.13.0",
73+
"@vercel/speed-insights": "^1.2.0",
7274
"autonumeric": "^4.10.8",
7375
"class-variance-authority": "^0.7.1",
7476
"clsx": "^2.1.1",
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
Warnings:
3+
4+
- Added the required column `githubUrl` to the `github_links` table without a default value. This is not possible if the table is not empty.
5+
- Changed the type of `githubId` on the `github_links` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required.
6+
- Changed the type of `githubType` on the `github_links` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required.
7+
8+
*/
9+
-- CreateEnum
10+
CREATE TYPE "GithubType" AS ENUM ('user', 'repo');
11+
12+
-- AlterTable
13+
ALTER TABLE "github_links" ADD COLUMN "githubUrl" TEXT NOT NULL,
14+
DROP COLUMN "githubId",
15+
ADD COLUMN "githubId" INTEGER NOT NULL,
16+
DROP COLUMN "githubType",
17+
ADD COLUMN "githubType" "GithubType" NOT NULL;

echo-control/src/app/(app)/@authenticated/(home)/(home)/page.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import { auth } from '@/auth';
88
export default async function DashboardPage() {
99
const session = await auth();
1010

11+
if (!session?.user) {
12+
return null;
13+
}
14+
1115
return (
1216
<div>
1317
<Heading

echo-control/src/app/(app)/@authenticated/_components/keys/generate-key.tsx

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useState } from 'react';
22

3-
import { Check, Copy, Info } from 'lucide-react';
3+
import { Info } from 'lucide-react';
44

55
import { toast } from 'sonner';
66

@@ -19,6 +19,7 @@ import {
1919
DialogTrigger,
2020
} from '@/components/ui/dialog';
2121
import { api } from '@/trpc/client';
22+
import { CopyButton } from '@/components/ui/copy-button';
2223

2324
interface Props {
2425
generateApiKey: (name?: string) => Promise<string>;
@@ -35,7 +36,7 @@ export const GenerateApiKey: React.FC<Props> = ({
3536
}) => {
3637
const [name, setName] = useState<string>();
3738

38-
const { isCopied, copyToClipboard } = useCopyToClipboard(() => {
39+
const { copyToClipboard } = useCopyToClipboard(() => {
3940
toast.success('Copied to clipboard');
4041
});
4142

@@ -52,18 +53,7 @@ export const GenerateApiKey: React.FC<Props> = ({
5253
<p className="flex-1 overflow-x-auto whitespace-nowrap font-mono text-sm no-scrollbar pr-2">
5354
{apiKey}
5455
</p>
55-
<Button
56-
onClick={() => copyToClipboard(apiKey)}
57-
variant="outline"
58-
className="shrink-0 size-fit p-2"
59-
size="icon"
60-
>
61-
{isCopied ? (
62-
<Check className="size-3" />
63-
) : (
64-
<Copy className="size-3" />
65-
)}
66-
</Button>
56+
<CopyButton text={apiKey} toastMessage="Copied to clipboard" />
6757
</div>
6858
</div>
6959

echo-control/src/app/(app)/@authenticated/_components/layout/nav/index.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Route } from 'next';
1010
interface Tab<T extends string> {
1111
label: string;
1212
href: Route<T>;
13+
subRoutes?: string[];
1314
}
1415

1516
interface Props<T extends string = string> {
@@ -60,7 +61,9 @@ export const Nav = <T extends string>({ tabs }: Props<T>) => {
6061
}
6162
}}
6263
>
63-
<MotionTab href={tab.href}>{tab.label}</MotionTab>
64+
<MotionTab href={tab.href} subRoutes={tab.subRoutes}>
65+
{tab.label}
66+
</MotionTab>
6467
</Link>
6568
</div>
6669
))}

echo-control/src/app/(app)/@authenticated/_components/layout/nav/motion-tab.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@ import { forwardRef } from 'react';
77
interface Props {
88
href: string;
99
children: React.ReactNode;
10+
subRoutes?: string[];
1011
}
1112

1213
export const MotionTab = forwardRef<HTMLLIElement, Props>(
13-
({ href, children }, ref) => {
14+
({ href, children, subRoutes }, ref) => {
1415
const pathname = usePathname();
1516

16-
const isSelected = pathname === href;
17+
const isSelected =
18+
pathname === href ||
19+
(subRoutes && subRoutes.some(route => pathname === route));
1720

1821
return (
1922
<motion.li key={href} ref={ref}>

echo-control/src/app/(app)/@authenticated/app/[id]/(overview)/_components/setup/recipient-details.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const tabsTriggerClassName =
2828
interface Props {
2929
githubLink: {
3030
type: GithubType;
31-
githubUrl: string;
31+
githubUrl: string | null;
3232
} | null;
3333
appId: string;
3434
}

echo-control/src/app/(app)/@authenticated/app/[id]/layout.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ export default async function AuthenticatedAppLayout({
2121
{
2222
label: 'Settings',
2323
href: `/app/${id}/settings`,
24+
subRoutes: [
25+
`/app/${id}/settings/general`,
26+
`/app/${id}/settings/monetization`,
27+
`/app/${id}/settings/security`,
28+
],
2429
},
2530
]}
2631
/>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
'use client';
2+
3+
import { Textarea } from '@/components/ui/textarea';
4+
5+
import { AppField } from './field';
6+
7+
export const AppDescription = () => {
8+
return (
9+
<AppField name="description">
10+
{field => <Textarea {...field} placeholder="My App" />}
11+
</AppField>
12+
);
13+
};
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use client';
2+
3+
import { ControllerRenderProps, useFormContext } from 'react-hook-form';
4+
5+
import {
6+
FormControl,
7+
FormField,
8+
FormItem,
9+
FormMessage,
10+
} from '@/components/ui/form';
11+
import { updateAppSchema } from '@/services/apps/owner';
12+
13+
interface Props {
14+
name: keyof typeof updateAppSchema.shape;
15+
children: (field: ControllerRenderProps) => React.ReactNode;
16+
}
17+
18+
export const AppField: React.FC<Props> = ({ name, children }) => {
19+
const form = useFormContext();
20+
21+
return (
22+
<FormField
23+
control={form.control}
24+
name={name}
25+
render={({ field }) => (
26+
<FormItem>
27+
<FormControl>{children(field)}</FormControl>
28+
<FormMessage />
29+
</FormItem>
30+
)}
31+
/>
32+
);
33+
};

0 commit comments

Comments
 (0)