create-githat-app 1.0.14 → 1.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +62 -18
- package/package.json +1 -1
- package/templates/agent/TODO.md +9 -0
- package/templates/agent/app/(auth)/sign-in/page.tsx.hbs +9 -0
- package/templates/agent/app/(auth)/sign-up/page.tsx.hbs +9 -0
- package/templates/agent/app/globals.css.hbs +87 -0
- package/templates/agent/app/layout.tsx.hbs +41 -0
- package/templates/agent/app/page.tsx.hbs +123 -0
- package/templates/agent/next.config.ts.hbs +7 -0
- package/templates/agent/postcss.config.mjs.hbs +14 -0
- package/templates/agent/proxy.ts.hbs +10 -0
- package/templates/agent/tsconfig.json.hbs +21 -0
- package/templates/content/TODO.md +9 -0
- package/templates/content/app/(auth)/sign-in/page.tsx.hbs +9 -0
- package/templates/content/app/(auth)/sign-up/page.tsx.hbs +9 -0
- package/templates/content/app/globals.css.hbs +87 -0
- package/templates/content/app/layout.tsx.hbs +41 -0
- package/templates/content/app/page.tsx.hbs +123 -0
- package/templates/content/next.config.ts.hbs +7 -0
- package/templates/content/postcss.config.mjs.hbs +14 -0
- package/templates/content/proxy.ts.hbs +10 -0
- package/templates/content/tsconfig.json.hbs +21 -0
- package/templates/dashboard/TODO.md +9 -0
- package/templates/dashboard/app/(auth)/sign-in/page.tsx.hbs +9 -0
- package/templates/dashboard/app/(auth)/sign-up/page.tsx.hbs +9 -0
- package/templates/dashboard/app/globals.css.hbs +87 -0
- package/templates/dashboard/app/layout.tsx.hbs +41 -0
- package/templates/dashboard/app/page.tsx.hbs +123 -0
- package/templates/dashboard/next.config.ts.hbs +7 -0
- package/templates/dashboard/postcss.config.mjs.hbs +14 -0
- package/templates/dashboard/proxy.ts.hbs +10 -0
- package/templates/dashboard/tsconfig.json.hbs +21 -0
- package/templates/marketplace/CULTURE.md +74 -0
- package/templates/marketplace/app/(auth)/sign-in/page.tsx.hbs +9 -0
- package/templates/marketplace/app/(auth)/sign-up/page.tsx.hbs +9 -0
- package/templates/marketplace/app/(shop)/[slug]/p/[productId]/page.tsx.hbs +99 -0
- package/templates/marketplace/app/(shop)/[slug]/page.tsx.hbs +90 -0
- package/templates/marketplace/app/admin/page.tsx.hbs +95 -0
- package/templates/marketplace/app/cart/page.tsx.hbs +157 -0
- package/templates/marketplace/app/globals.css.hbs +87 -0
- package/templates/marketplace/app/layout.tsx.hbs +77 -0
- package/templates/marketplace/app/page.tsx.hbs +178 -0
- package/templates/marketplace/app/sell/page.tsx.hbs +78 -0
- package/templates/marketplace/next.config.ts.hbs +7 -0
- package/templates/marketplace/postcss.config.mjs.hbs +14 -0
- package/templates/marketplace/proxy.ts.hbs +10 -0
- package/templates/marketplace/src/lib/anon-session.ts.hbs +117 -0
- package/templates/marketplace/src/lib/categories.ts.hbs +35 -0
- package/templates/marketplace/tsconfig.json.hbs +21 -0
- package/templates/saas/TODO.md +9 -0
- package/templates/saas/app/(auth)/sign-in/page.tsx.hbs +9 -0
- package/templates/saas/app/(auth)/sign-up/page.tsx.hbs +9 -0
- package/templates/saas/app/globals.css.hbs +87 -0
- package/templates/saas/app/layout.tsx.hbs +41 -0
- package/templates/saas/app/page.tsx.hbs +123 -0
- package/templates/saas/next.config.ts.hbs +7 -0
- package/templates/saas/postcss.config.mjs.hbs +14 -0
- package/templates/saas/proxy.ts.hbs +10 -0
- package/templates/saas/tsconfig.json.hbs +21 -0
package/dist/cli.js
CHANGED
|
@@ -11,7 +11,7 @@ import gradient from "gradient-string";
|
|
|
11
11
|
import chalk from "chalk";
|
|
12
12
|
|
|
13
13
|
// src/constants.ts
|
|
14
|
-
var VERSION = "1.0.
|
|
14
|
+
var VERSION = "1.0.15";
|
|
15
15
|
var DEFAULT_API_URL = "https://api.githat.io";
|
|
16
16
|
var DASHBOARD_URL = "https://githat.io/dashboard/apps";
|
|
17
17
|
var BRAND_COLORS = ["#7c3aed", "#6366f1", "#8b5cf6"];
|
|
@@ -330,9 +330,14 @@ function getInstallCommand(pm) {
|
|
|
330
330
|
async function promptFramework(typescriptOverride, isFullstack) {
|
|
331
331
|
const packageManager = detectPackageManager();
|
|
332
332
|
const frameworkOptions = isFullstack ? [{ value: "nextjs", label: "Next.js 16", hint: "App Router \xB7 SSR \xB7 middleware auth" }] : [
|
|
333
|
-
{ value: "plain", label: "Plain
|
|
334
|
-
{ value: "
|
|
335
|
-
{ value: "
|
|
333
|
+
{ value: "plain", label: "Plain", hint: "Auth + a homepage. Smallest possible GitHat app." },
|
|
334
|
+
{ value: "saas", label: "SaaS", hint: "Orgs, teams, RBAC, subscription billing. Replaces Clerk + Stripe." },
|
|
335
|
+
{ value: "marketplace", label: "Marketplace", hint: "Multi-vendor commerce. Anonymous-first browsing, Sebastn Connect." },
|
|
336
|
+
{ value: "agent", label: "AI Agent", hint: "Web4 wallet-bound agent + MCP server. Public verification." },
|
|
337
|
+
{ value: "content", label: "Content", hint: "Paywalled posts, newsletter, one-time purchases. Replaces Substack." },
|
|
338
|
+
{ value: "dashboard", label: "Dashboard", hint: "Auth-gated admin UI over your existing database." },
|
|
339
|
+
{ value: "nextjs", label: "Next.js (full kit)", hint: "Legacy: dashboard + orgs + agents + MCP scaffolding." },
|
|
340
|
+
{ value: "react-vite", label: "React + Vite", hint: "SPA \xB7 client-side routing." }
|
|
336
341
|
];
|
|
337
342
|
const answers = await p3.group(
|
|
338
343
|
{
|
|
@@ -584,10 +589,11 @@ async function promptFinalize() {
|
|
|
584
589
|
function toDisplayName(projectName) {
|
|
585
590
|
return projectName.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
586
591
|
}
|
|
587
|
-
function getDefaults(projectName, publishableKey, typescript, fullstack, backendFramework,
|
|
592
|
+
function getDefaults(projectName, publishableKey, typescript, fullstack, backendFramework, template) {
|
|
588
593
|
const displayName = toDisplayName(projectName);
|
|
589
594
|
const projectType = fullstack ? "fullstack" : "frontend";
|
|
590
|
-
const framework =
|
|
595
|
+
const framework = template ?? "nextjs";
|
|
596
|
+
const isMinimal = template !== void 0;
|
|
591
597
|
return {
|
|
592
598
|
projectName,
|
|
593
599
|
businessName: displayName,
|
|
@@ -599,19 +605,21 @@ function getDefaults(projectName, publishableKey, typescript, fullstack, backend
|
|
|
599
605
|
packageManager: detectPackageManager(),
|
|
600
606
|
publishableKey: publishableKey || "",
|
|
601
607
|
apiUrl: DEFAULT_API_URL,
|
|
602
|
-
authFeatures:
|
|
608
|
+
authFeatures: isMinimal ? [] : ["forgot-password"],
|
|
603
609
|
databaseChoice: "none",
|
|
604
610
|
useTailwind: true,
|
|
605
|
-
includeDashboard: !
|
|
606
|
-
includeGithatFolder: !
|
|
611
|
+
includeDashboard: !isMinimal,
|
|
612
|
+
includeGithatFolder: !isMinimal && projectType === "frontend",
|
|
607
613
|
initGit: true,
|
|
608
614
|
installDeps: true
|
|
609
615
|
};
|
|
610
616
|
}
|
|
611
617
|
async function runPrompts(args) {
|
|
612
618
|
if (args.yes && args.initialName) {
|
|
613
|
-
p8.log.info(
|
|
614
|
-
|
|
619
|
+
p8.log.info(
|
|
620
|
+
args.template ? `Using ${args.template} defaults (--yes --${args.template})` : "Using defaults (--yes flag)"
|
|
621
|
+
);
|
|
622
|
+
return getDefaults(args.initialName, args.publishableKey, args.typescript, args.fullstack, args.backendFramework, args.template);
|
|
615
623
|
}
|
|
616
624
|
p8.intro("Let's set up your GitHat app");
|
|
617
625
|
sectionHeader("Project");
|
|
@@ -678,8 +686,17 @@ var TEMPLATES_ROOT = path.resolve(__dirname2, "..", "templates");
|
|
|
678
686
|
Handlebars.registerHelper("ifEquals", function(a, b, options) {
|
|
679
687
|
return a === b ? options.fn(this) : options.inverse(this);
|
|
680
688
|
});
|
|
689
|
+
var NEXT_LIKE = /* @__PURE__ */ new Set([
|
|
690
|
+
"nextjs",
|
|
691
|
+
"plain",
|
|
692
|
+
"saas",
|
|
693
|
+
"marketplace",
|
|
694
|
+
"agent",
|
|
695
|
+
"content",
|
|
696
|
+
"dashboard"
|
|
697
|
+
]);
|
|
681
698
|
Handlebars.registerHelper("ifNext", function(framework, options) {
|
|
682
|
-
return framework
|
|
699
|
+
return NEXT_LIKE.has(framework) ? options.fn(this) : options.inverse(this);
|
|
683
700
|
});
|
|
684
701
|
function getTemplatesRoot() {
|
|
685
702
|
return TEMPLATES_ROOT;
|
|
@@ -727,18 +744,35 @@ function writeJson(root, relativePath, data) {
|
|
|
727
744
|
}
|
|
728
745
|
|
|
729
746
|
// src/scaffold/package-builder.ts
|
|
747
|
+
var NEXT_LIKE2 = /* @__PURE__ */ new Set([
|
|
748
|
+
"nextjs",
|
|
749
|
+
"plain",
|
|
750
|
+
"saas",
|
|
751
|
+
"marketplace",
|
|
752
|
+
"agent",
|
|
753
|
+
"content",
|
|
754
|
+
"dashboard"
|
|
755
|
+
]);
|
|
756
|
+
var MINIMAL = /* @__PURE__ */ new Set([
|
|
757
|
+
"plain",
|
|
758
|
+
"saas",
|
|
759
|
+
"marketplace",
|
|
760
|
+
"agent",
|
|
761
|
+
"content",
|
|
762
|
+
"dashboard"
|
|
763
|
+
]);
|
|
730
764
|
function buildPackageJson(ctx) {
|
|
731
|
-
const isNext =
|
|
765
|
+
const isNext = NEXT_LIKE2.has(ctx.framework);
|
|
732
766
|
const deps = {
|
|
733
767
|
...isNext ? DEPS.nextjs.dependencies : DEPS["react-vite"].dependencies
|
|
734
768
|
};
|
|
735
769
|
const devDeps = {
|
|
736
770
|
...isNext ? DEPS.nextjs.devDependencies : DEPS["react-vite"].devDependencies
|
|
737
771
|
};
|
|
738
|
-
if (ctx.framework
|
|
772
|
+
if (MINIMAL.has(ctx.framework)) {
|
|
739
773
|
delete deps["@githat/ui"];
|
|
740
774
|
}
|
|
741
|
-
if (ctx.useTailwind || ctx.framework
|
|
775
|
+
if (ctx.useTailwind || MINIMAL.has(ctx.framework)) {
|
|
742
776
|
if (isNext) {
|
|
743
777
|
Object.assign(devDeps, DEPS.tailwind.devDependencies);
|
|
744
778
|
} else {
|
|
@@ -932,7 +966,16 @@ async function scaffold(context, options) {
|
|
|
932
966
|
writeJson(root, "package.json", pkg);
|
|
933
967
|
}, "package.json generated");
|
|
934
968
|
}
|
|
935
|
-
|
|
969
|
+
const NEXT_LIKE3 = /* @__PURE__ */ new Set([
|
|
970
|
+
"nextjs",
|
|
971
|
+
"plain",
|
|
972
|
+
"saas",
|
|
973
|
+
"marketplace",
|
|
974
|
+
"agent",
|
|
975
|
+
"content",
|
|
976
|
+
"dashboard"
|
|
977
|
+
]);
|
|
978
|
+
if (!isFullstack && NEXT_LIKE3.has(context.framework)) {
|
|
936
979
|
await registerApp(context.projectName, root);
|
|
937
980
|
}
|
|
938
981
|
if (options.initGit) {
|
|
@@ -1587,7 +1630,7 @@ skillsCommand.action(() => {
|
|
|
1587
1630
|
// src/cli.ts
|
|
1588
1631
|
var program = new Command7();
|
|
1589
1632
|
program.name("githat").description("GitHat CLI - Scaffold apps and manage skills").version(VERSION);
|
|
1590
|
-
program.command("create [project-name]", { isDefault: true }).description("Scaffold a new GitHat app").option("--key <key>", "GitHat publishable key (pk_live_...)").option("--ts", "Use TypeScript (default)").option("--js", "Use JavaScript").option("--plain", "Smallest scaffold: auth + a homepage. No dashboard,
|
|
1633
|
+
program.command("create [project-name]", { isDefault: true }).description("Scaffold a new GitHat app").option("--key <key>", "GitHat publishable key (pk_live_...)").option("--ts", "Use TypeScript (default)").option("--js", "Use JavaScript").option("--plain", "Smallest scaffold: auth + a homepage. No dashboard.").option("--saas", "B2B starter: orgs, teams, RBAC, subscription billing.").option("--marketplace", "Multi-vendor commerce: anonymous-first browsing, Sebastn Connect.").option("--agent", "Web4 wallet-bound autonomous agent + MCP server registration.").option("--content", "Paywalled posts, newsletter, one-time purchases via Sebastn.").option("--dashboard", "Admin UI over your existing database, auth-gated.").option("--fullstack", "Create fullstack project (Turborepo)").option("--backend <framework>", "Backend framework (hono, express, fastify)").option("-y, --yes", "Skip prompts and use defaults").action(async (projectName, opts) => {
|
|
1591
1634
|
try {
|
|
1592
1635
|
displayBanner();
|
|
1593
1636
|
if (!opts.yes && !opts.key) {
|
|
@@ -1613,12 +1656,13 @@ program.command("create [project-name]", { isDefault: true }).description("Scaff
|
|
|
1613
1656
|
p12.cancel(chalk10.red("Project name is required when using --yes flag"));
|
|
1614
1657
|
process.exit(1);
|
|
1615
1658
|
}
|
|
1659
|
+
const template = opts.marketplace ? "marketplace" : opts.agent ? "agent" : opts.saas ? "saas" : opts.content ? "content" : opts.dashboard ? "dashboard" : opts.plain ? "plain" : void 0;
|
|
1616
1660
|
const answers = await runPrompts({
|
|
1617
1661
|
initialName: projectName,
|
|
1618
1662
|
publishableKey: opts.key,
|
|
1619
1663
|
typescript,
|
|
1620
1664
|
yes: opts.yes,
|
|
1621
|
-
|
|
1665
|
+
template,
|
|
1622
1666
|
fullstack: opts.fullstack,
|
|
1623
1667
|
backendFramework: opts.backend
|
|
1624
1668
|
});
|
package/package.json
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# agent template — placeholder
|
|
2
|
+
|
|
3
|
+
This template currently mirrors `plain`. The dedicated agent scaffold is
|
|
4
|
+
queued. See `../../TEMPLATES.md` for the full lineup and the
|
|
5
|
+
`saas` / `content` / `dashboard` / `ai-agent` rows for what each
|
|
6
|
+
should ultimately ship.
|
|
7
|
+
|
|
8
|
+
For now, `npx create-githat-app my-thing --agent` lays down the plain
|
|
9
|
+
template — auth + a homepage. Wire your agent-specific routes on top.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SignInForm } from '@githat/nextjs';
|
|
2
|
+
|
|
3
|
+
export default function SignInPage() {
|
|
4
|
+
return (
|
|
5
|
+
<main {{#if useTailwind}}className="flex items-center justify-center min-h-screen bg-[#09090b]"{{else}}style=\{{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', background: '#09090b' }}{{/if}}>
|
|
6
|
+
<SignInForm signUpUrl="/sign-up" {{#if includeForgotPassword}}forgotPasswordUrl="/forgot-password"{{/if}} />
|
|
7
|
+
</main>
|
|
8
|
+
);
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SignUpForm } from '@githat/nextjs';
|
|
2
|
+
|
|
3
|
+
export default function SignUpPage() {
|
|
4
|
+
return (
|
|
5
|
+
<main {{#if useTailwind}}className="flex items-center justify-center min-h-screen bg-[#09090b]"{{else}}style=\{{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', background: '#09090b' }}{{/if}}>
|
|
6
|
+
<SignUpForm signInUrl="/sign-in" />
|
|
7
|
+
</main>
|
|
8
|
+
);
|
|
9
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Tailwind v4 — required because @githat/nextjs/styles is processed
|
|
3
|
+
* through @tailwindcss/postcss. Plain doesn't ship utility classes,
|
|
4
|
+
* but the import is needed for the auth pages to render styled.
|
|
5
|
+
*/
|
|
6
|
+
@import "tailwindcss";
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
* Plain template — self-contained globals.
|
|
10
|
+
*
|
|
11
|
+
* Defines the minimum CSS variables a GitHat app uses for layout and
|
|
12
|
+
* the auth-page styling that ships with @githat/nextjs/styles.
|
|
13
|
+
* Override these in your own files when you want a real theme.
|
|
14
|
+
*
|
|
15
|
+
* Light theme by default; flip --bg/--fg for dark.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
:root {
|
|
19
|
+
/* Surface */
|
|
20
|
+
--bg: #ffffff;
|
|
21
|
+
--surface: #fafafa;
|
|
22
|
+
--surface-sub: #f4f4f5;
|
|
23
|
+
|
|
24
|
+
/* Borders */
|
|
25
|
+
--border: #e5e7eb;
|
|
26
|
+
|
|
27
|
+
/* Foreground */
|
|
28
|
+
--fg: #0a0a0a;
|
|
29
|
+
--fg-muted: #525252;
|
|
30
|
+
--fg-subtle: #737373;
|
|
31
|
+
|
|
32
|
+
/* Brand — change these two to re-skin the whole auth flow */
|
|
33
|
+
--primary: #6366f1;
|
|
34
|
+
--accent: #f59e0b;
|
|
35
|
+
|
|
36
|
+
/* Semantic */
|
|
37
|
+
--success: #16a34a;
|
|
38
|
+
--warn: #d97706;
|
|
39
|
+
--danger: #dc2626;
|
|
40
|
+
|
|
41
|
+
/* Spacing — used by @githat/nextjs/styles */
|
|
42
|
+
--space-1: 0.25rem;
|
|
43
|
+
--space-2: 0.5rem;
|
|
44
|
+
--space-3: 0.75rem;
|
|
45
|
+
--space-4: 1rem;
|
|
46
|
+
--space-6: 1.5rem;
|
|
47
|
+
--space-8: 2rem;
|
|
48
|
+
|
|
49
|
+
/* Radius */
|
|
50
|
+
--radius: 0.5rem;
|
|
51
|
+
--radius-md: 0.5rem;
|
|
52
|
+
--radius-lg: 0.75rem;
|
|
53
|
+
|
|
54
|
+
/* Fonts */
|
|
55
|
+
--font-sans: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
|
|
56
|
+
--font-wordmark: 'Instrument Serif', Georgia, serif;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@media (prefers-color-scheme: dark) {
|
|
60
|
+
:root {
|
|
61
|
+
--bg: #0a0a0a;
|
|
62
|
+
--surface: #18181b;
|
|
63
|
+
--surface-sub: #27272a;
|
|
64
|
+
--border: #3f3f46;
|
|
65
|
+
--fg: #fafafa;
|
|
66
|
+
--fg-muted: #a1a1aa;
|
|
67
|
+
--fg-subtle: #71717a;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
* {
|
|
72
|
+
box-sizing: border-box;
|
|
73
|
+
margin: 0;
|
|
74
|
+
padding: 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
body {
|
|
78
|
+
font-family: var(--font-sans);
|
|
79
|
+
background: var(--bg);
|
|
80
|
+
color: var(--fg);
|
|
81
|
+
line-height: 1.5;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
a {
|
|
85
|
+
color: inherit;
|
|
86
|
+
text-decoration: none;
|
|
87
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { GitHatProvider } from '@githat/nextjs';
|
|
2
|
+
import '@githat/nextjs/styles';
|
|
3
|
+
import './globals.css';
|
|
4
|
+
|
|
5
|
+
export const metadata = {
|
|
6
|
+
title: '{{businessName}}',
|
|
7
|
+
description: '{{description}}',
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default function RootLayout({ children }{{#if typescript}}: { children: React.ReactNode }{{/if}}) {
|
|
11
|
+
return (
|
|
12
|
+
<html lang="en">
|
|
13
|
+
<body>
|
|
14
|
+
{/*
|
|
15
|
+
Plain template: no @githat/ui dep, no Wordmark. The
|
|
16
|
+
full-kit (`nextjs`) template uses @githat/ui for the
|
|
17
|
+
shared design system; the plain scaffold is the smallest
|
|
18
|
+
working app, so we avoid extra deps.
|
|
19
|
+
*/}
|
|
20
|
+
<GitHatProvider config=\{{
|
|
21
|
+
publishableKey: process.env.NEXT_PUBLIC_GITHAT_PUBLISHABLE_KEY || '',
|
|
22
|
+
signInUrl: '/sign-in',
|
|
23
|
+
signUpUrl: '/sign-up',
|
|
24
|
+
afterSignInUrl: '/',
|
|
25
|
+
afterSignOutUrl: '/',
|
|
26
|
+
}}>
|
|
27
|
+
<header style=\{{
|
|
28
|
+
padding: '1rem 1.5rem',
|
|
29
|
+
borderBottom: '1px solid var(--border, #e5e7eb)',
|
|
30
|
+
fontFamily: 'system-ui, -apple-system, sans-serif',
|
|
31
|
+
}}>
|
|
32
|
+
<a href="/" style=\{{ textDecoration: 'none', color: 'inherit', fontWeight: 600 }}>
|
|
33
|
+
{{businessName}}
|
|
34
|
+
</a>
|
|
35
|
+
</header>
|
|
36
|
+
<main>{children}</main>
|
|
37
|
+
</GitHatProvider>
|
|
38
|
+
</body>
|
|
39
|
+
</html>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { SignInButton, SignUpButton, UserButton, useAuth } from '@githat/nextjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Plain GitHat homepage.
|
|
7
|
+
*
|
|
8
|
+
* No dashboard, no orgs, no agents — just one page that flips between
|
|
9
|
+
* "signed out" and "signed in." The smallest possible example of "I
|
|
10
|
+
* have GitHat wired up." Replace this file with whatever your app
|
|
11
|
+
* actually does — auth keeps working.
|
|
12
|
+
*/
|
|
13
|
+
export default function Home() {
|
|
14
|
+
const { isSignedIn, isLoading, user } = useAuth();
|
|
15
|
+
|
|
16
|
+
if (isLoading) {
|
|
17
|
+
return (
|
|
18
|
+
<div
|
|
19
|
+
style=\{{
|
|
20
|
+
display: 'flex',
|
|
21
|
+
minHeight: 'calc(100vh - 64px)',
|
|
22
|
+
alignItems: 'center',
|
|
23
|
+
justifyContent: 'center',
|
|
24
|
+
color: 'var(--fg-muted)',
|
|
25
|
+
}}
|
|
26
|
+
>
|
|
27
|
+
Loading…
|
|
28
|
+
</div>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<div
|
|
34
|
+
style=\{{
|
|
35
|
+
display: 'flex',
|
|
36
|
+
minHeight: 'calc(100vh - 64px)',
|
|
37
|
+
alignItems: 'center',
|
|
38
|
+
justifyContent: 'center',
|
|
39
|
+
padding: 'var(--space-8) var(--space-4)',
|
|
40
|
+
background: 'var(--bg)',
|
|
41
|
+
}}
|
|
42
|
+
>
|
|
43
|
+
<main
|
|
44
|
+
style=\{{
|
|
45
|
+
width: '100%',
|
|
46
|
+
maxWidth: '32rem',
|
|
47
|
+
textAlign: 'center',
|
|
48
|
+
color: 'var(--fg)',
|
|
49
|
+
}}
|
|
50
|
+
>
|
|
51
|
+
{!isSignedIn ? (
|
|
52
|
+
<>
|
|
53
|
+
<h1
|
|
54
|
+
style=\{{
|
|
55
|
+
fontFamily: 'var(--font-wordmark)',
|
|
56
|
+
fontSize: '2.5rem',
|
|
57
|
+
lineHeight: 1.1,
|
|
58
|
+
marginBottom: 'var(--space-3)',
|
|
59
|
+
}}
|
|
60
|
+
>
|
|
61
|
+
Welcome to {{businessName}}
|
|
62
|
+
</h1>
|
|
63
|
+
<p
|
|
64
|
+
style=\{{
|
|
65
|
+
color: 'var(--fg-muted)',
|
|
66
|
+
marginBottom: 'var(--space-6)',
|
|
67
|
+
lineHeight: 1.6,
|
|
68
|
+
}}
|
|
69
|
+
>
|
|
70
|
+
Sign in to continue, or create an account in 30 seconds.
|
|
71
|
+
We use GitHat for identity — your password never touches
|
|
72
|
+
this app.
|
|
73
|
+
</p>
|
|
74
|
+
<div
|
|
75
|
+
style=\{{
|
|
76
|
+
display: 'flex',
|
|
77
|
+
gap: 'var(--space-3)',
|
|
78
|
+
justifyContent: 'center',
|
|
79
|
+
flexWrap: 'wrap',
|
|
80
|
+
}}
|
|
81
|
+
>
|
|
82
|
+
<SignInButton />
|
|
83
|
+
<SignUpButton />
|
|
84
|
+
</div>
|
|
85
|
+
</>
|
|
86
|
+
) : (
|
|
87
|
+
<>
|
|
88
|
+
<div
|
|
89
|
+
style=\{{
|
|
90
|
+
display: 'flex',
|
|
91
|
+
alignItems: 'center',
|
|
92
|
+
justifyContent: 'center',
|
|
93
|
+
gap: 'var(--space-4)',
|
|
94
|
+
marginBottom: 'var(--space-6)',
|
|
95
|
+
}}
|
|
96
|
+
>
|
|
97
|
+
<UserButton />
|
|
98
|
+
<h1
|
|
99
|
+
style=\{{
|
|
100
|
+
fontFamily: 'var(--font-wordmark)',
|
|
101
|
+
fontSize: '2rem',
|
|
102
|
+
margin: 0,
|
|
103
|
+
}}
|
|
104
|
+
>
|
|
105
|
+
Hello{user?.name ? `, ${user.name}` : ''}.
|
|
106
|
+
</h1>
|
|
107
|
+
</div>
|
|
108
|
+
<p
|
|
109
|
+
style=\{{
|
|
110
|
+
color: 'var(--fg-muted)',
|
|
111
|
+
lineHeight: 1.6,
|
|
112
|
+
}}
|
|
113
|
+
>
|
|
114
|
+
That's it. The plain template doesn't ship a dashboard or
|
|
115
|
+
any other route — replace this page with whatever your
|
|
116
|
+
app actually does. Authentication will keep working.
|
|
117
|
+
</p>
|
|
118
|
+
</>
|
|
119
|
+
)}
|
|
120
|
+
</main>
|
|
121
|
+
</div>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Plain template — Tailwind v4 PostCSS plugin is required even though
|
|
3
|
+
* the plain scaffold doesn't use Tailwind utility classes. The auth
|
|
4
|
+
* page CSS shipped by `@githat/nextjs/styles` is processed through
|
|
5
|
+
* @tailwindcss/postcss at build time. Drop this config and the
|
|
6
|
+
* auth pages render unstyled.
|
|
7
|
+
*/
|
|
8
|
+
const config = {
|
|
9
|
+
plugins: {
|
|
10
|
+
'@tailwindcss/postcss': {},
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default config;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { authProxy } from '@githat/nextjs/proxy';
|
|
2
|
+
|
|
3
|
+
export const proxy = authProxy({
|
|
4
|
+
publicRoutes: ['/', '/sign-in', '/sign-up'{{#if includeForgotPassword}}, '/forgot-password', '/reset-password'{{/if}}{{#if includeEmailVerification}}, '/verify-email'{{/if}}],
|
|
5
|
+
signInUrl: '/sign-in',
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export const config = {
|
|
9
|
+
matcher: ['/((?!_next|api|.*\\..*).*)'],
|
|
10
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2017",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"allowJs": true,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"module": "esnext",
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"jsx": "preserve",
|
|
15
|
+
"incremental": true,
|
|
16
|
+
"plugins": [{ "name": "next" }],
|
|
17
|
+
"paths": { "@/*": ["./*"] }
|
|
18
|
+
},
|
|
19
|
+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
20
|
+
"exclude": ["node_modules"]
|
|
21
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# content template — placeholder
|
|
2
|
+
|
|
3
|
+
This template currently mirrors `plain`. The dedicated content scaffold is
|
|
4
|
+
queued. See `../../TEMPLATES.md` for the full lineup and the
|
|
5
|
+
`saas` / `content` / `dashboard` / `ai-agent` rows for what each
|
|
6
|
+
should ultimately ship.
|
|
7
|
+
|
|
8
|
+
For now, `npx create-githat-app my-thing --content` lays down the plain
|
|
9
|
+
template — auth + a homepage. Wire your content-specific routes on top.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SignInForm } from '@githat/nextjs';
|
|
2
|
+
|
|
3
|
+
export default function SignInPage() {
|
|
4
|
+
return (
|
|
5
|
+
<main {{#if useTailwind}}className="flex items-center justify-center min-h-screen bg-[#09090b]"{{else}}style=\{{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', background: '#09090b' }}{{/if}}>
|
|
6
|
+
<SignInForm signUpUrl="/sign-up" {{#if includeForgotPassword}}forgotPasswordUrl="/forgot-password"{{/if}} />
|
|
7
|
+
</main>
|
|
8
|
+
);
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SignUpForm } from '@githat/nextjs';
|
|
2
|
+
|
|
3
|
+
export default function SignUpPage() {
|
|
4
|
+
return (
|
|
5
|
+
<main {{#if useTailwind}}className="flex items-center justify-center min-h-screen bg-[#09090b]"{{else}}style=\{{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', background: '#09090b' }}{{/if}}>
|
|
6
|
+
<SignUpForm signInUrl="/sign-in" />
|
|
7
|
+
</main>
|
|
8
|
+
);
|
|
9
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Tailwind v4 — required because @githat/nextjs/styles is processed
|
|
3
|
+
* through @tailwindcss/postcss. Plain doesn't ship utility classes,
|
|
4
|
+
* but the import is needed for the auth pages to render styled.
|
|
5
|
+
*/
|
|
6
|
+
@import "tailwindcss";
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
* Plain template — self-contained globals.
|
|
10
|
+
*
|
|
11
|
+
* Defines the minimum CSS variables a GitHat app uses for layout and
|
|
12
|
+
* the auth-page styling that ships with @githat/nextjs/styles.
|
|
13
|
+
* Override these in your own files when you want a real theme.
|
|
14
|
+
*
|
|
15
|
+
* Light theme by default; flip --bg/--fg for dark.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
:root {
|
|
19
|
+
/* Surface */
|
|
20
|
+
--bg: #ffffff;
|
|
21
|
+
--surface: #fafafa;
|
|
22
|
+
--surface-sub: #f4f4f5;
|
|
23
|
+
|
|
24
|
+
/* Borders */
|
|
25
|
+
--border: #e5e7eb;
|
|
26
|
+
|
|
27
|
+
/* Foreground */
|
|
28
|
+
--fg: #0a0a0a;
|
|
29
|
+
--fg-muted: #525252;
|
|
30
|
+
--fg-subtle: #737373;
|
|
31
|
+
|
|
32
|
+
/* Brand — change these two to re-skin the whole auth flow */
|
|
33
|
+
--primary: #6366f1;
|
|
34
|
+
--accent: #f59e0b;
|
|
35
|
+
|
|
36
|
+
/* Semantic */
|
|
37
|
+
--success: #16a34a;
|
|
38
|
+
--warn: #d97706;
|
|
39
|
+
--danger: #dc2626;
|
|
40
|
+
|
|
41
|
+
/* Spacing — used by @githat/nextjs/styles */
|
|
42
|
+
--space-1: 0.25rem;
|
|
43
|
+
--space-2: 0.5rem;
|
|
44
|
+
--space-3: 0.75rem;
|
|
45
|
+
--space-4: 1rem;
|
|
46
|
+
--space-6: 1.5rem;
|
|
47
|
+
--space-8: 2rem;
|
|
48
|
+
|
|
49
|
+
/* Radius */
|
|
50
|
+
--radius: 0.5rem;
|
|
51
|
+
--radius-md: 0.5rem;
|
|
52
|
+
--radius-lg: 0.75rem;
|
|
53
|
+
|
|
54
|
+
/* Fonts */
|
|
55
|
+
--font-sans: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
|
|
56
|
+
--font-wordmark: 'Instrument Serif', Georgia, serif;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@media (prefers-color-scheme: dark) {
|
|
60
|
+
:root {
|
|
61
|
+
--bg: #0a0a0a;
|
|
62
|
+
--surface: #18181b;
|
|
63
|
+
--surface-sub: #27272a;
|
|
64
|
+
--border: #3f3f46;
|
|
65
|
+
--fg: #fafafa;
|
|
66
|
+
--fg-muted: #a1a1aa;
|
|
67
|
+
--fg-subtle: #71717a;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
* {
|
|
72
|
+
box-sizing: border-box;
|
|
73
|
+
margin: 0;
|
|
74
|
+
padding: 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
body {
|
|
78
|
+
font-family: var(--font-sans);
|
|
79
|
+
background: var(--bg);
|
|
80
|
+
color: var(--fg);
|
|
81
|
+
line-height: 1.5;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
a {
|
|
85
|
+
color: inherit;
|
|
86
|
+
text-decoration: none;
|
|
87
|
+
}
|