Add Vynte scheduler app shell
This commit is contained in:
@@ -0,0 +1,15 @@
|
|||||||
|
* { box-sizing: border-box; }
|
||||||
|
html, body { margin: 0; min-height: 100%; background: #f4f5f7; color: #202226; font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; }
|
||||||
|
button, input, select, textarea { font: inherit; }
|
||||||
|
a { color: inherit; text-decoration: none; }
|
||||||
|
.app-frame { min-height: 100vh; display: grid; grid-template-columns: 196px minmax(0, 1fr); background: #f4f5f7; }
|
||||||
|
.sidebar { min-height: 100vh; border-right: 1px solid #e3e5e8; background: #fafafa; padding: 18px 12px; display: flex; flex-direction: column; }
|
||||||
|
.brand { font-size: 16px; font-weight: 750; padding: 3px 8px 20px; }
|
||||||
|
.nav-list { display: grid; gap: 4px; }
|
||||||
|
.nav-item { padding: 9px 10px; border-radius: 5px; color: #555a61; font-size: 13px; font-weight: 600; }
|
||||||
|
.nav-item[data-active="true"] { background: #e9efec; color: #204d39; }
|
||||||
|
.profile-block { margin-top: auto; border-top: 1px solid #e3e5e8; padding: 14px 8px 2px; font-size: 12px; }
|
||||||
|
.profile-block strong { display: block; font-size: 13px; margin-bottom: 2px; }
|
||||||
|
.profile-block span { color: #777c83; }
|
||||||
|
.main-surface { padding: 20px; min-width: 0; }
|
||||||
|
@media (max-width: 860px) { .app-frame { grid-template-columns: 1fr; } .sidebar { min-height: auto; border-right: 0; border-bottom: 1px solid #e3e5e8; } }
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import type { Metadata } from "next";
|
||||||
|
import "./globals.css";
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Vynte Schedule",
|
||||||
|
description: "Internal Vynte team scheduling",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
||||||
|
return (
|
||||||
|
<html lang="en">
|
||||||
|
<body>{children}</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
redirect("/calendar");
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
type ActiveNavItem = "calendar" | "availability" | "connections";
|
||||||
|
type NavItem = { id: ActiveNavItem; href: string; label: string };
|
||||||
|
|
||||||
|
const navItems: NavItem[] = [
|
||||||
|
{ id: "calendar", href: "/calendar", label: "Calendar" },
|
||||||
|
{ id: "availability", href: "/availability", label: "Availability" },
|
||||||
|
{ id: "connections", href: "/connections", label: "Connections" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export function AppShell({
|
||||||
|
active,
|
||||||
|
user,
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
active: ActiveNavItem;
|
||||||
|
user: { name: string; timeZone: string };
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="app-frame">
|
||||||
|
<aside className="sidebar">
|
||||||
|
<div className="brand">Vynte Schedule</div>
|
||||||
|
<nav className="nav-list" aria-label="Scheduler navigation">
|
||||||
|
{navItems.map((item) => (
|
||||||
|
<Link key={item.id} className="nav-item" data-active={item.id === active} href={item.href}>
|
||||||
|
{item.label}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
<div className="profile-block">
|
||||||
|
<strong>{user.name}</strong>
|
||||||
|
<span>{user.timeZone}</span>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
<main className="main-surface">{children}</main>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Vendored
+2
@@ -0,0 +1,2 @@
|
|||||||
|
/// <reference types="next" />
|
||||||
|
/// <reference types="next/image-types/global" />
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import type { NextConfig } from "next";
|
||||||
|
|
||||||
|
const nextConfig: NextConfig = {
|
||||||
|
transpilePackages: ["@calcom/dayjs", "@calcom/features", "@calcom/lib", "@calcom/prisma", "@calcom/types"],
|
||||||
|
experimental: {
|
||||||
|
externalDir: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default nextConfig;
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"name": "@vynte/scheduler",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next dev --port 3040",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start --port 3040",
|
||||||
|
"lint": "biome lint .",
|
||||||
|
"type-check": "tsc --noEmit",
|
||||||
|
"test": "vitest run"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@calcom/dayjs": "workspace:*",
|
||||||
|
"@calcom/features": "workspace:*",
|
||||||
|
"@calcom/lib": "workspace:*",
|
||||||
|
"@calcom/prisma": "workspace:*",
|
||||||
|
"@calcom/tsconfig": "workspace:*",
|
||||||
|
"@calcom/types": "workspace:*",
|
||||||
|
"next": "16.2.3",
|
||||||
|
"next-auth": "4.24.13",
|
||||||
|
"react": "18.2.0",
|
||||||
|
"react-dom": "18.2.0",
|
||||||
|
"zod": "3.25.76"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.17.23",
|
||||||
|
"@types/react": "18.0.26",
|
||||||
|
"@types/react-dom": "^18.0.9",
|
||||||
|
"typescript": "5.9.3",
|
||||||
|
"vitest": "4.1.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"extends": "@calcom/tsconfig/nextjs.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@scheduler/*": ["./*"]
|
||||||
|
},
|
||||||
|
"plugins": [{ "name": "next" }],
|
||||||
|
"strictNullChecks": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"next-env.d.ts",
|
||||||
|
"../../packages/types/*.d.ts",
|
||||||
|
"../../packages/types/next-auth.d.ts",
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx",
|
||||||
|
".next/types/**/*.ts"
|
||||||
|
],
|
||||||
|
"exclude": ["node_modules", ".next"]
|
||||||
|
}
|
||||||
@@ -17651,6 +17651,29 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@vynte/scheduler@workspace:apps/scheduler":
|
||||||
|
version: 0.0.0-use.local
|
||||||
|
resolution: "@vynte/scheduler@workspace:apps/scheduler"
|
||||||
|
dependencies:
|
||||||
|
"@calcom/dayjs": "workspace:*"
|
||||||
|
"@calcom/features": "workspace:*"
|
||||||
|
"@calcom/lib": "workspace:*"
|
||||||
|
"@calcom/prisma": "workspace:*"
|
||||||
|
"@calcom/tsconfig": "workspace:*"
|
||||||
|
"@calcom/types": "workspace:*"
|
||||||
|
"@types/node": "npm:^20.17.23"
|
||||||
|
"@types/react": "npm:18.0.26"
|
||||||
|
"@types/react-dom": "npm:^18.0.9"
|
||||||
|
next: "npm:16.2.3"
|
||||||
|
next-auth: "npm:4.24.13"
|
||||||
|
react: "npm:18.2.0"
|
||||||
|
react-dom: "npm:18.2.0"
|
||||||
|
typescript: "npm:5.9.3"
|
||||||
|
vitest: "npm:4.1.8"
|
||||||
|
zod: "npm:3.25.76"
|
||||||
|
languageName: unknown
|
||||||
|
linkType: soft
|
||||||
|
|
||||||
"@webassemblyjs/ast@npm:1.14.1, @webassemblyjs/ast@npm:^1.14.1":
|
"@webassemblyjs/ast@npm:1.14.1, @webassemblyjs/ast@npm:^1.14.1":
|
||||||
version: 1.14.1
|
version: 1.14.1
|
||||||
resolution: "@webassemblyjs/ast@npm:1.14.1"
|
resolution: "@webassemblyjs/ast@npm:1.14.1"
|
||||||
|
|||||||
Reference in New Issue
Block a user