Select the types of activity you want to include in your feed.
One Calendar is a privacy-first calendar web app built with Next.js. It has modern security features, including e2ee, password-protected sharing, and self-destructing share links ๐
calendar.xyehr.cn
···11-
11+<div align="center">
22+ <img src="public/icon.svg" width="72">
33+</div>
44+55+# One Calendar
66+77+[](https://vercel.com/new/clone?repository-url=https://github.com/Dev-Huang1/One-Calendar&env=NEXT_PUBLIC_BASE_URL,NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY,CLERK_SECRET_KEY,OPENWEATHER_API_KEY,BLOB_READ_WRITE_TOKEN&project-name=one-calendar&repo-name=one-calendar)
88+99+A beautifully minimal open-source calendar app to plan your week and life.
1010+1111+## What is One Calendar?
1212+1313+**One Calendar** is a privacy-first, weekly-focused, open-source calendar app, designed to help individuals and teams plan, focus, and stay in sync.
1414+1515+> Without *One Calendar*, your schedule is scattered. With it, your week feels intentional.
1616+1717+## Why One Calendar?
1818+1919+Most calendar tools are cluttered, over-engineered, or locked behind paywalls. One Calendar aims to be:
2020+2121+- ๐ง **Simple and Intuitive** โ Weekly view first, with minimal distractions.
2222+- ๐น **Interactive & Smooth** โ Drag, drop, right-click, and edit with ease.
2323+- ๐ **Private & Local** โ Your data is yours. Export, backup, and control.
2424+- โ๏ธ **Cloud Sync** โ Optional sync via Supabase and Vercel Blob.
2525+- ๐ **Multi-Account Google Sync** โ Easily sync with Google Calendar.
2626+- ๐ **International** โ Automatically adapts to your language (English / ไธญๆ).
2727+- ๐งฑ **Customizable** โ Tailor themes, default view, and integrations.
2828+2929+## Tech Stack
3030+3131+- **Frontend**: Next.js 14, Tailwind CSS, shadcn/ui, TypeScript
3232+- **Auth**: Clerk
3333+- **Storage**: LocalStorage, Vercel Blob
3434+- **Weather**: OpenWeather API
3535+3636+## Preview
3737+3838+
3939+
4040+4141+## Quick Start
4242+4343+```bash
4444+# Clone the repo
4545+git clone https://github.com/Dev-Huang1/One-Calendar.git
4646+cd One-Calendar
4747+4848+# Install dependencies
4949+bun install
2505151+# Start the app
5252+bun run dev
5353+```
35444-# One Calendar
5555+Then visit `http://localhost:3000`
55666-One Calendar is a calendar web app that uses React + Vercel/blob for storage. It has rich features: address book, notes, bookmarks, to-do lists and analysis features! ๐ ๐๏ธ
5757+## Environment Variables
5858+5959+Copy `.env.example` to `.env.local` and fill in:
6060+6161+```env
6262+NEXT_PUBLIC_BASE_URL=your_url
6363+NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your-clerk-publishable-key
6464+CLERK_SECRET_KEY=your-clerk-secret
6565+OPENWEATHER_API_KEY=your-open-weather-api-key
6666+BLOB_READ_WRITE_TOKEN=your-vercel-blob-token
6767+```
6868+6969+## Star History
7070+7171+[](https://www.star-history.com/#Dev-Huang1/One-Calendar&Date)
7272+7373+## The Team
7474+7575+Brought to you by a small team of makers who love clean tools and open-source.
7676+7777+Check out our [contributors](https://github.com/Dev-Huang1/One-Calendar/graphs/contributors) โค๏ธ
7878+7979+## Acknowledgements
8080+8181+This project wouldn't be possible without these awesome services:
8282+8383+<div style="display: flex; justify-content: center;">
8484+ <a href="https://vercel.com" style="text-decoration: none;">
8585+ <img src="https://github.com/user-attachments/assets/5107d47f-7ce9-425a-8e24-77c322205bd4" alt="Vercel" width="96"/>
8686+ </a>
8787+ <a href="https://clerk.com" style="text-decoration: none;">
8888+ <img src="https://github.com/user-attachments/assets/6f9fa5d7-e0c2-4c14-aef9-e39bd0465e23" alt="Clerk" width="96"/>
8989+ </a>
9090+ <a href="https://openweathermap.org" style="text-decoration: none;">
9191+ <img src="https://github.com/user-attachments/assets/d07ed7a1-c374-45f5-90fd-17c3de2a9098" alt="OpenWeather API" width="96"/>
9292+ </a>
9393+</div>
9494+9595+## License
9696+9797+[GPL 3.0 Licensed](./LICENSE). Copyright ยฉ Tech-Art-Studio 2025.
app/about/page.tsx
app/(app)/about/page.tsx
app/app/page.tsx
app/(app)/app/page.tsx
+2-2
app/layout.tsx
···22import type { Metadata } from "next"
33import "./globals.css"
44import { Toaster } from "@/components/ui/toaster"
55-import { CalendarProvider } from "@/contexts/CalendarContext"
55+import { CalendarProvider } from "@/components/context/CalendarContext"
66import { Analytics } from '@vercel/analytics/next';
77import { SpeedInsights } from "@vercel/speed-insights/next"
88import { ClerkProvider } from '@clerk/nextjs'
99import { enUS } from '@clerk/localizations'
1010import { GeistSans } from "geist/font/sans"
1111-import { ThemeProvider } from "@/components/theme-provider"
1111+import { ThemeProvider } from "@/components/context/theme-provider"
12121313export const metadata: Metadata = {
1414 title: "One Calendar",
+1-1
app/page.tsx
···11-import LandingPage from "@/components/Landing"
11+import LandingPage from "@/components/home/Landing"
2233export default function Landing() {
44 return <LandingPage />
···44import TimeAnalyticsComponent from "./TimeAnalytics"
55import ImportExport from "./ImportExport"
66import AnalyticsGuide from "./AnalyticsGuide"
77-import type { CalendarEvent } from "./Calendar"
88-import { useCalendar } from "@/contexts/CalendarContext"
77+import type { CalendarEvent } from "../Calendar"
88+import { useCalendar } from "@/components/context/CalendarContext"
99import { useLanguage } from "@/hooks/useLanguage"
1010import { translations } from "@/lib/i18n"
1111import ShareManagement from "./ShareManagement"
···66import { Input } from "@/components/ui/input"
77import { ChevronLeft, ChevronRight, Search, PanelLeft } from 'lucide-react'
88import { addDays, subDays } from "date-fns"
99-import Sidebar from "./Sidebar"
1010-import DayView from "./DayView"
1111-import WeekView from "./WeekView"
1212-import MonthView from "./MonthView"
1313-import EventDialog from "./EventDialog"
1414-import Settings from "./Settings"
99+import Sidebar from "@/components/sidebar/Sidebar"
1010+import DayView from "@/components/view/DayView"
1111+import WeekView from "@/components/view/WeekView"
1212+import MonthView from "@/components/view/MonthView"
1313+import EventDialog from "@/components/event/EventDialog"
1414+import Settings from "@/components/home/Settings"
1515import { translations, useLanguage } from "@/lib/i18n"
1616import { checkPendingNotifications, clearAllNotificationTimers, type NOTIFICATION_SOUNDS } from "@/lib/notifications"
1717-import EventPreview from "./EventPreview"
1717+import EventPreview from "@/components/event/EventPreview"
1818import { useLocalStorage } from "@/hooks/useLocalStorage"
1919-import { useCalendar } from "@/contexts/CalendarContext"
2020-import EventUrlHandler from "./EventUrlHandler"
2121-import RightSidebar from "./RightSidebar"
2222-import AnalyticsView from "./AnalyticsView"
1919+import { useCalendar } from "@/components/context/CalendarContext"
2020+import EventUrlHandler from "@/components/event/EventUrlHandler"
2121+import RightSidebar from "@/components/sidebar/RightSidebar"
2222+import AnalyticsView from "@/components/analytics/AnalyticsView"
2323import { ScrollArea } from "@/components/ui/scroll-area"
2424-import UserProfileButton from "./UserProfileButton"
2424+import UserProfileButton from "@/components/home/UserProfileButton"
2525import { cn } from "@/lib/utils"
2626-import Weather from "./Weather"
2727-import DailyToast from "./DailyToast"
2828-import QuickStartGuide from "./QuickStartGuide"
2626+import Weather from "@/components/home/Weather"
2727+import DailyToast from "@/components/home/DailyToast"
2828+import QuickStartGuide from "@/components/home/QuickStartGuide"
29293030type ViewType = "day" | "week" | "month" | "analytics"
3131
···1212import { format, isSameDay, isWithinInterval, endOfDay, startOfDay } from "date-fns"
1313import { zhCN, enUS } from "date-fns/locale"
1414import { cn } from "@/lib/utils"
1515-import type { CalendarEvent } from "./Calendar"
1515+import type { CalendarEvent } from "../Calendar"
1616import type { Language } from "@/lib/i18n"
17171818interface DayViewProps {
···2020import { Button } from "@/components/ui/button"
2121import { zhCN, enUS } from "date-fns/locale"
2222import { format } from "date-fns"
2323-import type { CalendarEvent } from "./Calendar"
2323+import type { CalendarEvent } from "../Calendar"
2424import type { Language } from "@/lib/i18n"
2525import { translations } from "@/lib/i18n"
2626import { cn } from "@/lib/utils"
2727-import { useCalendar } from "@/contexts/CalendarContext"
2727+import { useCalendar } from "@/components/context/CalendarContext"
2828import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog"
2929import { Input } from "@/components/ui/input"
3030import { Label } from "@/components/ui/label"
···2233import { format, startOfMonth, endOfMonth, eachDayOfInterval, isSameMonth, isSameDay } from "date-fns"
44import { cn } from "@/lib/utils"
55-import type { CalendarEvent } from "./Calendar"
55+import type { CalendarEvent } from "../Calendar"
6677type Language = "en" | "zh"
88
···1111import { Label } from "@/components/ui/label"
1212import { Plus, X } from "lucide-react"
1313import { cn } from "@/lib/utils"
1414-import type { CalendarEvent } from "./Calendar"
1515-import type { CalendarCategory } from "./Sidebar"
1414+import type { CalendarEvent } from "../Calendar"
1515+import type { CalendarCategory } from "../Sidebar"
1616import { translations, useLanguage } from "@/lib/i18n"
17171818interface TimeAnalyticsProps {