├── packages ├── google-calendar │ ├── src │ │ ├── resources.ts │ │ ├── version.ts │ │ ├── error.ts │ │ ├── uploads.ts │ │ ├── resource.ts │ │ ├── api-promise.ts │ │ ├── core │ │ │ ├── README.md │ │ │ ├── uploads.ts │ │ │ ├── resource.ts │ │ │ └── api-promise.ts │ │ ├── internal │ │ │ ├── README.md │ │ │ ├── utils │ │ │ │ ├── sleep.ts │ │ │ │ ├── uuid.ts │ │ │ │ ├── env.ts │ │ │ │ ├── bytes.ts │ │ │ │ ├── base64.ts │ │ │ │ ├── path.ts │ │ │ │ ├── values.ts │ │ │ │ └── log.ts │ │ │ ├── utils.ts │ │ │ ├── shim-types.d.ts │ │ │ ├── errors.ts │ │ │ ├── request-options.ts │ │ │ ├── parse.ts │ │ │ ├── builtin-types.ts │ │ │ ├── headers.ts │ │ │ └── shims.ts │ │ ├── resources │ │ │ ├── users.ts │ │ │ ├── users │ │ │ │ ├── me.ts │ │ │ │ ├── index.ts │ │ │ │ ├── users.ts │ │ │ │ └── me │ │ │ │ │ ├── index.ts │ │ │ │ │ └── me.ts │ │ │ ├── calendars.ts │ │ │ ├── index.ts │ │ │ ├── calendars │ │ │ │ └── index.ts │ │ │ ├── colors.ts │ │ │ ├── free-busy.ts │ │ │ └── channels.ts │ │ └── index.ts │ ├── tsconfig.json │ └── package.json ├── lib │ ├── index.ts │ ├── package.json │ └── constants.ts ├── db │ ├── tsconfig.json │ ├── drizzle.config.ts │ ├── index.ts │ ├── drizzle │ │ ├── migrations │ │ │ ├── meta │ │ │ │ └── _journal.json │ │ │ ├── 0001_regular_abomination.sql │ │ │ └── 0000_curved_supernaut.sql │ │ └── schema.ts │ └── package.json ├── env │ ├── tsconfig.json │ ├── package.json │ └── index.js ├── api │ ├── tsconfig.json │ ├── index.ts │ ├── package.json │ └── src │ │ ├── root.ts │ │ ├── routers │ │ ├── schema.ts │ │ └── account.ts │ │ ├── utils │ │ └── accounts.ts │ │ └── trpc.ts └── auth │ ├── tsconfig.json │ ├── package.json │ ├── auth-client.ts │ └── index.ts ├── apps └── web │ ├── public │ ├── calendar.png │ ├── weekday-dark.PNG │ └── weekday-light.PNG │ ├── components │ ├── event-calendar │ │ ├── hooks │ │ │ ├── index.ts │ │ │ ├── use-dynamic-week-cell-height.ts │ │ │ ├── use-current-time-indicator.ts │ │ │ └── use-event-visibility.ts │ │ ├── constants.ts │ │ ├── index.ts │ │ ├── types.ts │ │ ├── calendar-context.tsx │ │ ├── droppable-cell.tsx │ │ └── views │ │ │ └── agenda-view.tsx │ ├── ui │ │ ├── skeleton.tsx │ │ ├── label.tsx │ │ ├── sonner.tsx │ │ ├── textarea.tsx │ │ ├── separator.tsx │ │ ├── collapsible.tsx │ │ ├── avatar.tsx │ │ ├── input.tsx │ │ ├── hover-card.tsx │ │ ├── radio-group.tsx │ │ ├── badge.tsx │ │ ├── scroll-area.tsx │ │ ├── popover.tsx │ │ ├── tooltip.tsx │ │ ├── resizable.tsx │ │ ├── button.tsx │ │ ├── card.tsx │ │ ├── checkbox.tsx │ │ └── calendar-days.tsx │ ├── ai │ │ ├── image.tsx │ │ ├── response.tsx │ │ ├── suggestion.tsx │ │ ├── actions.tsx │ │ ├── message.tsx │ │ ├── conversation.tsx │ │ └── loader.tsx │ ├── chat │ │ ├── chat-button.tsx │ │ ├── chat-prompt-input.tsx │ │ └── tools │ │ │ ├── get-upcoming-event.tsx │ │ │ └── get-free-slots.tsx │ ├── resizable-panels-client.tsx │ ├── participants.tsx │ ├── footer-section.tsx │ ├── theme-toggle.tsx │ ├── features-section.tsx │ ├── sidebar-calendar.tsx │ ├── hero-section.tsx │ ├── header.tsx │ └── app-sidebar.tsx │ ├── app │ ├── api │ │ ├── auth │ │ │ └── [...all] │ │ │ │ └── route.ts │ │ ├── trpc │ │ │ └── [trpc] │ │ │ │ └── route.ts │ │ └── ai │ │ │ └── chat │ │ │ └── route.ts │ ├── page.tsx │ ├── calendar │ │ └── page.tsx │ ├── layout.tsx │ └── login │ │ └── page.tsx │ ├── prettier.config.js │ ├── postcss.config.js │ ├── providers │ ├── theme-provider.tsx │ └── chat-provider.tsx │ ├── hooks │ ├── use-calendar-view.ts │ └── use-mobile.ts │ ├── components.json │ ├── trpc │ ├── query-client.ts │ ├── server.ts │ └── react.tsx │ ├── tsconfig.json │ ├── middleware.ts │ ├── next.config.js │ ├── lib │ └── utils.ts │ └── package.json ├── docker-compose.yml ├── tsconfig.base.json ├── .gitignore ├── turbo.json ├── package.json ├── .env.example └── readme.md /packages/google-calendar/src/resources.ts: -------------------------------------------------------------------------------- 1 | export * from './resources/index'; 2 | -------------------------------------------------------------------------------- /packages/google-calendar/src/version.ts: -------------------------------------------------------------------------------- 1 | export const VERSION = '0.0.1-alpha.0'; 2 | -------------------------------------------------------------------------------- /packages/lib/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./calendar"; 2 | export * from "./constants"; 3 | -------------------------------------------------------------------------------- /apps/web/public/calendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ephraimduncan/weekday/HEAD/apps/web/public/calendar.png -------------------------------------------------------------------------------- /packages/db/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["index.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /packages/env/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["index.js"] 4 | } 5 | -------------------------------------------------------------------------------- /apps/web/public/weekday-dark.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ephraimduncan/weekday/HEAD/apps/web/public/weekday-dark.PNG -------------------------------------------------------------------------------- /apps/web/public/weekday-light.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ephraimduncan/weekday/HEAD/apps/web/public/weekday-light.PNG -------------------------------------------------------------------------------- /packages/api/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["src", "index.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /packages/auth/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["**/*.ts", "**/*.tsx"] 4 | } 5 | -------------------------------------------------------------------------------- /packages/google-calendar/src/error.ts: -------------------------------------------------------------------------------- 1 | /** @deprecated Import from ./core/error instead */ 2 | export * from "./core/error"; 3 | -------------------------------------------------------------------------------- /packages/google-calendar/src/uploads.ts: -------------------------------------------------------------------------------- 1 | /** @deprecated Import from ./core/uploads instead */ 2 | export * from './core/uploads'; 3 | -------------------------------------------------------------------------------- /packages/google-calendar/src/resource.ts: -------------------------------------------------------------------------------- 1 | /** @deprecated Import from ./core/resource instead */ 2 | export * from './core/resource'; 3 | -------------------------------------------------------------------------------- /packages/google-calendar/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["**/*.ts", "**/*.tsx"] 4 | } 5 | -------------------------------------------------------------------------------- /packages/google-calendar/src/api-promise.ts: -------------------------------------------------------------------------------- 1 | /** @deprecated Import from ./core/api-promise instead */ 2 | export * from './core/api-promise'; 3 | -------------------------------------------------------------------------------- /apps/web/components/event-calendar/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./use-current-time-indicator"; 2 | export * from "./use-dynamic-week-cell-height"; 3 | -------------------------------------------------------------------------------- /packages/google-calendar/src/core/README.md: -------------------------------------------------------------------------------- 1 | # `core` 2 | 3 | This directory holds public modules implementing non-resource-specific SDK functionality. 4 | -------------------------------------------------------------------------------- /apps/web/app/api/auth/[...all]/route.ts: -------------------------------------------------------------------------------- 1 | import { handler, toNextJsHandler } from "@weekday/auth"; 2 | 3 | export const { GET, POST } = toNextJsHandler(handler); 4 | -------------------------------------------------------------------------------- /packages/google-calendar/src/core/uploads.ts: -------------------------------------------------------------------------------- 1 | export { type Uploadable } from '../internal/uploads'; 2 | export { toFile, type ToFileInput } from '../internal/to-file'; 3 | -------------------------------------------------------------------------------- /packages/google-calendar/src/internal/README.md: -------------------------------------------------------------------------------- 1 | # `internal` 2 | 3 | The modules in this directory are not importable outside this package and will change between releases. 4 | -------------------------------------------------------------------------------- /packages/google-calendar/src/resources/users.ts: -------------------------------------------------------------------------------- 1 | // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | export * from './users/index'; 4 | -------------------------------------------------------------------------------- /packages/google-calendar/src/resources/users/me.ts: -------------------------------------------------------------------------------- 1 | // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | export * from './me/index'; 4 | -------------------------------------------------------------------------------- /packages/google-calendar/src/resources/calendars.ts: -------------------------------------------------------------------------------- 1 | // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | export * from "./calendars/index"; 4 | -------------------------------------------------------------------------------- /apps/web/prettier.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('prettier').Config & import('prettier-plugin-tailwindcss').PluginOptions} */ 2 | export default { 3 | plugins: ["prettier-plugin-tailwindcss"], 4 | }; 5 | -------------------------------------------------------------------------------- /apps/web/postcss.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | "@tailwindcss/postcss": {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /packages/google-calendar/src/resources/users/index.ts: -------------------------------------------------------------------------------- 1 | // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | export { Me } from './me/index'; 4 | export { Users } from './users'; 5 | -------------------------------------------------------------------------------- /packages/google-calendar/src/internal/utils/sleep.ts: -------------------------------------------------------------------------------- 1 | // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); 4 | -------------------------------------------------------------------------------- /packages/api/index.ts: -------------------------------------------------------------------------------- 1 | export { appRouter } from "./src/root"; 2 | export type { AppRouter } from "./src/root"; 3 | 4 | export { createCaller } from "./src/root"; 5 | export * from "./src/routers/schema"; 6 | export { createTRPCContext } from "./src/trpc"; 7 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.8' 2 | 3 | services: 4 | postgres: 5 | image: postgres:16 6 | restart: always 7 | environment: 8 | POSTGRES_USER: postgres 9 | POSTGRES_PASSWORD: password 10 | POSTGRES_DB: postgres 11 | ports: 12 | - '5433:5432' -------------------------------------------------------------------------------- /apps/web/providers/theme-provider.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { 4 | type ThemeProviderProps, 5 | ThemeProvider as NextThemesProvider, 6 | } from "next-themes"; 7 | 8 | export function ThemeProvider({ children, ...props }: ThemeProviderProps) { 9 | return {children}; 10 | } 11 | -------------------------------------------------------------------------------- /packages/google-calendar/src/internal/utils.ts: -------------------------------------------------------------------------------- 1 | // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | export * from './utils/values'; 4 | export * from './utils/base64'; 5 | export * from './utils/env'; 6 | export * from './utils/log'; 7 | export * from './utils/uuid'; 8 | export * from './utils/sleep'; 9 | -------------------------------------------------------------------------------- /packages/google-calendar/src/core/resource.ts: -------------------------------------------------------------------------------- 1 | // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | import type { GoogleCalendar } from "../client"; 4 | 5 | export class APIResource { 6 | protected _client: GoogleCalendar; 7 | 8 | constructor(client: GoogleCalendar) { 9 | this._client = client; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /apps/web/components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils"; 2 | 3 | function Skeleton({ className, ...props }: React.ComponentProps<"div">) { 4 | return ( 5 |
10 | ); 11 | } 12 | 13 | export { Skeleton }; 14 | -------------------------------------------------------------------------------- /packages/db/drizzle.config.ts: -------------------------------------------------------------------------------- 1 | import { env } from "@weekday/env"; 2 | import { defineConfig } from "drizzle-kit"; 3 | 4 | export default defineConfig({ 5 | dialect: "postgresql", 6 | schema: "./drizzle/schema.ts", 7 | out: "./drizzle/migrations", 8 | dbCredentials: { 9 | url: env.DATABASE_URL, 10 | }, 11 | verbose: true, 12 | strict: true, 13 | }); 14 | -------------------------------------------------------------------------------- /packages/db/index.ts: -------------------------------------------------------------------------------- 1 | import { env } from "@weekday/env"; 2 | import { drizzle } from "drizzle-orm/node-postgres"; 3 | import { eq } from "drizzle-orm"; 4 | import * as schema from "./drizzle/schema"; 5 | 6 | export const db = drizzle(env.DATABASE_URL, { schema }); 7 | export type DrizzleClient = typeof db; 8 | export * from "./drizzle/schema"; 9 | export { schema, eq }; 10 | -------------------------------------------------------------------------------- /packages/env/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@weekday/env", 3 | "version": "0.0.0", 4 | "main": "./index.js", 5 | "type": "module", 6 | "scripts": { 7 | "lint": "eslint *.ts*" 8 | }, 9 | "dependencies": { 10 | "@t3-oss/env-nextjs": "^0.12.0", 11 | "zod": "^3.24.2" 12 | }, 13 | "devDependencies": { 14 | "eslint": "^9.23.0", 15 | "typescript": "^5.8.2" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/lib/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@weekday/lib", 3 | "version": "0.0.0", 4 | "main": "./index.ts", 5 | "types": "./index.ts", 6 | "scripts": { 7 | "lint": "eslint *.ts*" 8 | }, 9 | "dependencies": { 10 | "@weekday/db": "*", 11 | "@weekday/google-calendar": "*", 12 | "zod": "^3.24.2" 13 | }, 14 | "devDependencies": { 15 | "eslint": "^9.23.0", 16 | "typescript": "^5.8.2" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/google-calendar/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@weekday/google-calendar", 3 | "version": "0.0.0", 4 | "main": "./src/index.ts", 5 | "types": "./src/index.ts", 6 | "exports": { 7 | ".": "./src/index.ts" 8 | }, 9 | "scripts": { 10 | "lint": "eslint *.ts*" 11 | }, 12 | "dependencies": { 13 | "@weekday/db": "*" 14 | }, 15 | "devDependencies": { 16 | "eslint": "^9.23.0", 17 | "typescript": "^5.8.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /apps/web/hooks/use-calendar-view.ts: -------------------------------------------------------------------------------- 1 | import type { CalendarView } from "@/components/event-calendar"; 2 | 3 | import { useAtom } from "jotai"; 4 | import { atomWithStorage } from "jotai/utils"; 5 | 6 | type CalendarViewConfig = { 7 | view: CalendarView; 8 | }; 9 | 10 | const calendarViewAtom = atomWithStorage("calendar-view", { 11 | view: "week", 12 | }); 13 | 14 | export function useCalendarView() { 15 | return useAtom(calendarViewAtom); 16 | } 17 | -------------------------------------------------------------------------------- /packages/auth/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@weekday/auth", 3 | "version": "0.0.0", 4 | "main": "./src/index.ts", 5 | "types": "./src/index.ts", 6 | "scripts": { 7 | "lint": "eslint *.ts*" 8 | }, 9 | "dependencies": { 10 | "@weekday/db": "*", 11 | "@weekday/env": "*", 12 | "better-auth": "^1.2.9", 13 | "next": "^15.4.0-canary.50" 14 | }, 15 | "devDependencies": { 16 | "eslint": "^9.23.0", 17 | "typescript": "^5.8.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/google-calendar/src/resources/users/users.ts: -------------------------------------------------------------------------------- 1 | // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | import { APIResource } from '../../core/resource'; 4 | import * as MeAPI from './me/me'; 5 | import { Me } from './me/me'; 6 | 7 | export class Users extends APIResource { 8 | me: MeAPI.Me = new MeAPI.Me(this._client); 9 | } 10 | 11 | Users.Me = Me; 12 | 13 | export declare namespace Users { 14 | export { Me as Me }; 15 | } 16 | -------------------------------------------------------------------------------- /packages/db/drizzle/migrations/meta/_journal.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "7", 3 | "dialect": "postgresql", 4 | "entries": [ 5 | { 6 | "idx": 0, 7 | "version": "7", 8 | "when": 1747955444125, 9 | "tag": "0000_curved_supernaut", 10 | "breakpoints": true 11 | }, 12 | { 13 | "idx": 1, 14 | "version": "7", 15 | "when": 1750133058662, 16 | "tag": "0001_regular_abomination", 17 | "breakpoints": true 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /apps/web/app/page.tsx: -------------------------------------------------------------------------------- 1 | import { FeaturesSection } from "@/components/features-section"; 2 | import FooterSection from "@/components/footer-section"; 3 | import { HeroSection } from "@/components/hero-section"; 4 | 5 | export const metadata = { 6 | description: "Your calendar, reimagined with AI", 7 | title: "Weekday", 8 | }; 9 | 10 | export default function Home() { 11 | return ( 12 |
13 | 14 | 15 | 16 |
17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /apps/web/components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "", 8 | "css": "app/globals.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "ai": "@/components/ai", 18 | "lib": "@/lib", 19 | "hooks": "@/hooks" 20 | }, 21 | "iconLibrary": "lucide" 22 | } 23 | -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2020", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true, 17 | "noUncheckedIndexedAccess": true 18 | }, 19 | "exclude": ["node_modules"] 20 | } 21 | -------------------------------------------------------------------------------- /apps/web/components/ai/image.tsx: -------------------------------------------------------------------------------- 1 | import type { Experimental_GeneratedImage } from "ai"; 2 | 3 | import { cn } from "@/lib/utils"; 4 | 5 | export type ImageProps = Experimental_GeneratedImage & { 6 | alt?: string; 7 | className?: string; 8 | }; 9 | 10 | export const Image = ({ 11 | base64, 12 | mediaType, 13 | uint8Array, 14 | ...props 15 | }: ImageProps) => ( 16 | {props.alt} 25 | ); 26 | -------------------------------------------------------------------------------- /packages/api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@weekday/api", 3 | "version": "0.0.0", 4 | "main": "./src/index.ts", 5 | "types": "./src/index.ts", 6 | "scripts": { 7 | "lint": "eslint *.ts*" 8 | }, 9 | "dependencies": { 10 | "@weekday/auth": "*", 11 | "@weekday/google-calendar": "*", 12 | "@weekday/db": "*", 13 | "@weekday/lib": "*", 14 | "@trpc/server": "^11.0.0", 15 | "@trpc/client": "^11.0.0", 16 | "superjson": "^2.2.1", 17 | "uuid": "^11.1.0", 18 | "zod": "^3.24.2" 19 | }, 20 | "devDependencies": { 21 | "eslint": "^9.23.0", 22 | "typescript": "^5.8.2" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/google-calendar/src/resources/users/me/index.ts: -------------------------------------------------------------------------------- 1 | // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | export { 4 | CalendarList, 5 | type CalendarListEntry, 6 | type CalendarListListResponse, 7 | type CalendarListCreateParams, 8 | type CalendarListUpdateParams, 9 | type CalendarListListParams, 10 | type CalendarListWatchParams, 11 | } from './calendar-list'; 12 | export { Me } from './me'; 13 | export { 14 | Settings, 15 | type SettingRetrieveResponse, 16 | type SettingListResponse, 17 | type SettingListParams, 18 | type SettingWatchParams, 19 | } from './settings'; 20 | -------------------------------------------------------------------------------- /packages/google-calendar/src/resources/index.ts: -------------------------------------------------------------------------------- 1 | // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | export { 4 | Calendars, 5 | type Calendar, 6 | type CalendarCreateParams, 7 | type CalendarUpdateParams, 8 | type CalendarUpdatePartialParams, 9 | } from './calendars/calendars'; 10 | export { Channels, type ChannelStopWatchingParams } from './channels'; 11 | export { Colors, type ColorListResponse } from './colors'; 12 | export { 13 | FreeBusy, 14 | type FreeBusyCheckAvailabilityResponse, 15 | type FreeBusyCheckAvailabilityParams, 16 | } from './free-busy'; 17 | export { Users } from './users/users'; 18 | -------------------------------------------------------------------------------- /packages/lib/constants.ts: -------------------------------------------------------------------------------- 1 | export const GOOGLE_CALENDAR_LIST_API_URL = 2 | "https://www.googleapis.com/calendar/v3/users/me/calendarList"; 3 | 4 | export const GOOGLE_FREEBUSY_API_URL = 5 | "https://www.googleapis.com/calendar/v3/freeBusy"; 6 | 7 | export const GOOGLE_CALENDAR_COLORS: Record = { 8 | "1": { color: "blue" }, 9 | "2": { color: "emerald" }, 10 | "3": { color: "violet" }, 11 | "4": { color: "rose" }, 12 | "5": { color: "yellow" }, 13 | "6": { color: "orange" }, 14 | "7": { color: "cyan" }, 15 | "8": { color: "gray" }, 16 | "9": { color: "indigo" }, 17 | "10": { color: "green" }, 18 | "11": { color: "red" }, 19 | }; 20 | -------------------------------------------------------------------------------- /apps/web/components/ai/response.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { type ComponentProps, memo } from "react"; 4 | 5 | import { Streamdown } from "streamdown"; 6 | 7 | import { cn } from "@/lib/utils"; 8 | 9 | type ResponseProps = ComponentProps; 10 | 11 | export const Response = memo( 12 | ({ className, ...props }: ResponseProps) => ( 13 | *:first-child]:mt-0 [&>*:last-child]:mb-0", 16 | className, 17 | )} 18 | {...props} 19 | /> 20 | ), 21 | (prevProps, nextProps) => prevProps.children === nextProps.children, 22 | ); 23 | 24 | Response.displayName = "Response"; 25 | -------------------------------------------------------------------------------- /apps/web/hooks/use-mobile.ts: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | const MOBILE_BREAKPOINT = 1024; 4 | 5 | export function useIsMobile() { 6 | const [isMobile, setIsMobile] = React.useState( 7 | undefined, 8 | ); 9 | 10 | React.useEffect(() => { 11 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`); 12 | const onChange = () => { 13 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT); 14 | }; 15 | mql.addEventListener("change", onChange); 16 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT); 17 | return () => mql.removeEventListener("change", onChange); 18 | }, []); 19 | 20 | return !!isMobile; 21 | } 22 | -------------------------------------------------------------------------------- /packages/db/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@weekday/db", 3 | "version": "0.0.0", 4 | "main": "./index.ts", 5 | "types": "./index.ts", 6 | "scripts": { 7 | "generate": "bun run with:env drizzle-kit generate", 8 | "migrate": "bun run with:env drizzle-kit migrate", 9 | "push": "bun run with:env drizzle-kit push", 10 | "studio": "bun run with:env drizzle-kit studio", 11 | "with:env": "dotenv -e ../../.env --" 12 | }, 13 | "dependencies": { 14 | "@weekday/env": "*", 15 | "drizzle-orm": "^0.43.1", 16 | "pg": "^8.16.0" 17 | }, 18 | "devDependencies": { 19 | "@types/pg": "^8.15.2", 20 | "drizzle-kit": "^0.31.1", 21 | "typescript": "^5.8.2" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/google-calendar/src/internal/utils/uuid.ts: -------------------------------------------------------------------------------- 1 | // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | /** 4 | * https://stackoverflow.com/a/2117523 5 | */ 6 | export let uuid4 = function () { 7 | const { crypto } = globalThis as any; 8 | if (crypto?.randomUUID) { 9 | uuid4 = crypto.randomUUID.bind(crypto); 10 | return crypto.randomUUID(); 11 | } 12 | const u8 = new Uint8Array(1); 13 | const randomByte = crypto ? () => crypto.getRandomValues(u8)[0]! : () => (Math.random() * 0xff) & 0xff; 14 | return '10000000-1000-4000-8000-100000000000'.replace(/[018]/g, (c) => 15 | (+c ^ (randomByte() & (15 >> (+c / 4)))).toString(16), 16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /packages/google-calendar/src/internal/utils/env.ts: -------------------------------------------------------------------------------- 1 | // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | /** 4 | * Read an environment variable. 5 | * 6 | * Trims beginning and trailing whitespace. 7 | * 8 | * Will return undefined if the environment variable doesn't exist or cannot be accessed. 9 | */ 10 | export const readEnv = (env: string): string | undefined => { 11 | if (typeof (globalThis as any).process !== 'undefined') { 12 | return (globalThis as any).process.env?.[env]?.trim() ?? undefined; 13 | } 14 | if (typeof (globalThis as any).Deno !== 'undefined') { 15 | return (globalThis as any).Deno.env?.get?.(env)?.trim(); 16 | } 17 | return undefined; 18 | }; 19 | -------------------------------------------------------------------------------- /packages/db/drizzle/migrations/0001_regular_abomination.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE "weekday_account" DROP CONSTRAINT "weekday_account_user_id_weekday_user_id_fk"; 2 | --> statement-breakpoint 3 | ALTER TABLE "weekday_account" ADD COLUMN "name" text DEFAULT '' NOT NULL;--> statement-breakpoint 4 | ALTER TABLE "weekday_account" ADD COLUMN "email" text DEFAULT '' NOT NULL;--> statement-breakpoint 5 | ALTER TABLE "weekday_account" ADD COLUMN "image" text;--> statement-breakpoint 6 | ALTER TABLE "weekday_user" ADD COLUMN "default_account_id" text;--> statement-breakpoint 7 | ALTER TABLE "weekday_account" ADD CONSTRAINT "weekday_account_user_id_weekday_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."weekday_user"("id") ON DELETE cascade ON UPDATE no action; -------------------------------------------------------------------------------- /apps/web/components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import * as React from "react"; 4 | 5 | import * as LabelPrimitive from "@radix-ui/react-label"; 6 | 7 | import { cn } from "@/lib/utils"; 8 | 9 | function Label({ 10 | className, 11 | ...props 12 | }: React.ComponentProps) { 13 | return ( 14 | 22 | ); 23 | } 24 | 25 | export { Label }; 26 | -------------------------------------------------------------------------------- /apps/web/components/event-calendar/constants.ts: -------------------------------------------------------------------------------- 1 | export const EventHeight = 24; 2 | 3 | // Vertical gap between events in pixels - controls spacing in month view 4 | export const EventGap = 4; 5 | 6 | // Height of hour cells in week and day views - controls the scale of time display 7 | // export const WeekCellsHeight = 48; 8 | export const WeekCellsHeight = 75; 9 | 10 | // Number of days to show in the agenda view 11 | export const AgendaDaysToShow = 30; 12 | 13 | // Start and end hours for the week and day views 14 | // export const StartHour = 0; 15 | // export const EndHour = 24; 16 | export const StartHour = 6; 17 | export const EndHour = 21; 18 | 19 | // Default start and end times 20 | export const DefaultStartHour = 9; // 9 AM 21 | export const DefaultEndHour = 10; // 10 AM 22 | -------------------------------------------------------------------------------- /packages/auth/auth-client.ts: -------------------------------------------------------------------------------- 1 | import { multiSessionClient } from "better-auth/client/plugins"; 2 | import { createAuthClient } from "better-auth/react"; 3 | 4 | export const authClient = createAuthClient({ 5 | plugins: [multiSessionClient()], 6 | }); 7 | 8 | export const { 9 | signIn, 10 | signOut, 11 | useSession, 12 | linkSocial, 13 | unlinkAccount, 14 | listAccounts, 15 | } = authClient; 16 | 17 | export const multiSession = { 18 | listDeviceSessions: () => authClient.multiSession.listDeviceSessions(), 19 | setActive: (sessionToken: string) => 20 | authClient.multiSession.setActive({ sessionToken }), 21 | revoke: (sessionToken: string) => 22 | authClient.multiSession.revoke({ sessionToken }), 23 | }; 24 | 25 | export type Session = typeof authClient.$Infer.Session; 26 | -------------------------------------------------------------------------------- /packages/api/src/root.ts: -------------------------------------------------------------------------------- 1 | import { createCallerFactory, createTRPCRouter } from "./trpc"; 2 | import { calendarRouter } from "./routers/calendar"; 3 | import { accountRouter } from "./routers/account"; 4 | 5 | /** 6 | * This is the primary router for your server. 7 | * 8 | * All routers added in /api/routers should be manually added here. 9 | */ 10 | export const appRouter = createTRPCRouter({ 11 | calendar: calendarRouter, 12 | account: accountRouter, 13 | }); 14 | 15 | // export type definition of API 16 | export type AppRouter = typeof appRouter; 17 | 18 | /** 19 | * Create a server-side caller for the tRPC API. 20 | * @example 21 | * const trpc = createCaller(createContext); 22 | * const res = await trpc.post.all(); 23 | * ^? Post[] 24 | */ 25 | export const createCaller = createCallerFactory(appRouter); 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | .pnp 6 | .pnp.js 7 | 8 | # testing 9 | coverage 10 | 11 | # next.js 12 | .next/ 13 | out/ 14 | next-env.d.ts 15 | 16 | # nitro 17 | .nitro/ 18 | .output/ 19 | 20 | # expo 21 | .expo/ 22 | expo-env.d.ts 23 | apps/expo/.gitignore 24 | apps/expo/ios 25 | apps/expo/android 26 | 27 | # production 28 | build 29 | 30 | # misc 31 | .DS_Store 32 | **/.DS_Store 33 | *.pem 34 | 35 | # debug 36 | npm-debug.log* 37 | yarn-debug.log* 38 | yarn-error.log* 39 | .pnpm-debug.log* 40 | 41 | # local env files 42 | .env 43 | .env*.local 44 | 45 | # vercel 46 | .vercel 47 | 48 | # typescript 49 | dist/ 50 | .cache 51 | 52 | # turbo 53 | .turbo 54 | 55 | .cursor 56 | .claude 57 | CLAUDE.md 58 | 59 | *.tsbuildinfo -------------------------------------------------------------------------------- /apps/web/components/ui/sonner.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { useTheme } from "next-themes"; 4 | import { type ToasterProps, Toaster as Sonner } from "sonner"; 5 | 6 | const Toaster = ({ ...props }: ToasterProps) => { 7 | const { theme = "system" } = useTheme(); 8 | 9 | return ( 10 | 27 | ); 28 | }; 29 | 30 | export { Toaster }; 31 | -------------------------------------------------------------------------------- /apps/web/components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "@/lib/utils"; 4 | 5 | function Textarea({ className, ...props }: React.ComponentProps<"textarea">) { 6 | return ( 7 |