diff --git a/package-lock.json b/package-lock.json
index 0634924..d818a57 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,12 +9,18 @@
"version": "0.0.1-alpha.0",
"dependencies": {
"@radix-ui/react-checkbox": "^1.1.4",
+ "@radix-ui/react-context-menu": "^2.2.6",
"@radix-ui/react-dialog": "^1.1.6",
"@radix-ui/react-label": "^2.1.2",
"@radix-ui/react-separator": "^1.1.2",
"@radix-ui/react-slot": "^1.1.2",
"@radix-ui/react-tabs": "^1.1.3",
"@radix-ui/react-tooltip": "^1.1.8",
+ "@schedule-x/drag-and-drop": "^2.19.0",
+ "@schedule-x/events-service": "^2.19.0",
+ "@schedule-x/react": "^2.19.0",
+ "@schedule-x/theme-shadcn": "^2.19.0",
+ "@types/react-big-calendar": "^1.16.1",
"axios": "^1.7.9",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
@@ -727,6 +733,34 @@
"node": ">=14"
}
},
+ "node_modules/@preact/signals": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@preact/signals/-/signals-1.3.2.tgz",
+ "integrity": "sha512-naxcJgUJ6BTOROJ7C3QML7KvwKwCXQJYTc5L/b0eEsdYgPB6SxwoQ1vDGcS0Q7GVjAenVq/tXrybVdFShHYZWg==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@preact/signals-core": "^1.7.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ },
+ "peerDependencies": {
+ "preact": "10.x"
+ }
+ },
+ "node_modules/@preact/signals-core": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.8.0.tgz",
+ "integrity": "sha512-OBvUsRZqNmjzCZXWLxkZfhcgT+Fk8DDcT/8vD6a1xhDemodyy87UJRJfASMuSD8FaAIeGgGm85ydXhm7lr4fyA==",
+ "license": "MIT",
+ "peer": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ }
+ },
"node_modules/@radix-ui/primitive": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz",
@@ -842,6 +876,34 @@
}
}
},
+ "node_modules/@radix-ui/react-context-menu": {
+ "version": "2.2.6",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.2.6.tgz",
+ "integrity": "sha512-aUP99QZ3VU84NPsHeaFt4cQUNgJqFsLLOt/RbbWXszZ6MP0DpDyjkFZORr4RpAEx3sUBk+Kc8h13yGtC5Qw8dg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.1",
+ "@radix-ui/react-context": "1.1.1",
+ "@radix-ui/react-menu": "2.1.6",
+ "@radix-ui/react-primitive": "2.0.2",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-dialog": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.6.tgz",
@@ -1001,6 +1063,46 @@
}
}
},
+ "node_modules/@radix-ui/react-menu": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.6.tgz",
+ "integrity": "sha512-tBBb5CXDJW3t2mo9WlO7r6GTmWV0F0uzHZVFmlRmYpiSK1CDU5IKojP1pm7oknpBOrFZx/YgBRW9oorPO2S/Lg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.1",
+ "@radix-ui/react-collection": "1.1.2",
+ "@radix-ui/react-compose-refs": "1.1.1",
+ "@radix-ui/react-context": "1.1.1",
+ "@radix-ui/react-direction": "1.1.0",
+ "@radix-ui/react-dismissable-layer": "1.1.5",
+ "@radix-ui/react-focus-guards": "1.1.1",
+ "@radix-ui/react-focus-scope": "1.1.2",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-popper": "1.2.2",
+ "@radix-ui/react-portal": "1.1.4",
+ "@radix-ui/react-presence": "1.1.2",
+ "@radix-ui/react-primitive": "2.0.2",
+ "@radix-ui/react-roving-focus": "1.1.2",
+ "@radix-ui/react-slot": "1.1.2",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.6.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-popper": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.2.tgz",
@@ -1386,6 +1488,46 @@
"integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==",
"license": "MIT"
},
+ "node_modules/@schedule-x/calendar": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/@schedule-x/calendar/-/calendar-2.19.0.tgz",
+ "integrity": "sha512-XgGWX1iV7mwJw+Zr7dSUhhGbV2Z3OTdD2BsuUMfMlKutbWb3qXzqL4I+jernTgRhY0M1310i5lm7LJ5/hOpJqQ==",
+ "license": "MIT",
+ "peer": true,
+ "peerDependencies": {
+ "@preact/signals": "^1.1.5",
+ "preact": "^10.19.2"
+ }
+ },
+ "node_modules/@schedule-x/drag-and-drop": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/@schedule-x/drag-and-drop/-/drag-and-drop-2.19.0.tgz",
+ "integrity": "sha512-xlBNzAK7BvtCt3AS6anHT8hC0m58J/Sof/YYgH9XzwxwgksEkzO9/A+NUFMh5w2O/JK77cRO8858WJqJINPbUw==",
+ "license": "MIT"
+ },
+ "node_modules/@schedule-x/events-service": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/@schedule-x/events-service/-/events-service-2.19.0.tgz",
+ "integrity": "sha512-klOOKRM6HE0scP8+cgZOG8/g3ahxip0l1ubc5REz6EX5pcmvQ1DbjKgk0O80XSWrJga20Ppbw32oduMmt2BvFw==",
+ "license": "MIT"
+ },
+ "node_modules/@schedule-x/react": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/@schedule-x/react/-/react-2.19.0.tgz",
+ "integrity": "sha512-w6JrjFFJqXKvYQPb7DIdOp0llGkB+QZ6pWyUqxXEEspyY2iIjWMzcoR+PKEAK+wKlS8TCj/fG2KdFxLxU5Ltag==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@schedule-x/calendar": "^2.18.0",
+ "react": "^16.7.0 || ^17 || ^18 || ^19",
+ "react-dom": "^16.7.0 || ^17 || ^18 || ^19"
+ }
+ },
+ "node_modules/@schedule-x/theme-shadcn": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/@schedule-x/theme-shadcn/-/theme-shadcn-2.19.0.tgz",
+ "integrity": "sha512-ntyJ57r35qmHjj992TUQwdz4wIWqrULsFiNRexQAiMHgG+qqBBfWLcBaLPGy4qcmjv1cOY1HCABM4idQozDhaw==",
+ "license": "MIT"
+ },
"node_modules/@swc/counter": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
@@ -1464,6 +1606,12 @@
"integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==",
"license": "MIT"
},
+ "node_modules/@types/date-arithmetic": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/@types/date-arithmetic/-/date-arithmetic-4.1.4.tgz",
+ "integrity": "sha512-p9eZ2X9B80iKiTW4ukVj8B4K6q9/+xFtQ5MGYA5HWToY9nL4EkhV9+6ftT2VHpVMEZb5Tv00Iel516bVdO+yRw==",
+ "license": "MIT"
+ },
"node_modules/@types/node": {
"version": "20.17.19",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.19.tgz",
@@ -1478,20 +1626,29 @@
"version": "15.7.14",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
"integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==",
- "devOptional": true,
"license": "MIT"
},
"node_modules/@types/react": {
"version": "18.3.18",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz",
"integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==",
- "devOptional": true,
"license": "MIT",
"dependencies": {
"@types/prop-types": "*",
"csstype": "^3.0.2"
}
},
+ "node_modules/@types/react-big-calendar": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/@types/react-big-calendar/-/react-big-calendar-1.16.1.tgz",
+ "integrity": "sha512-pDHFcVWx+BvZbX6U39R4l8c9930vKnfx+09lf4W8r8HuxBDLzGk7Q63ncBmqqnQImEFNDKfwa6MDyu90cfzJ2A==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/date-arithmetic": "*",
+ "@types/prop-types": "*",
+ "@types/react": "*"
+ }
+ },
"node_modules/@types/react-dom": {
"version": "18.3.5",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz",
@@ -2896,6 +3053,17 @@
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
"license": "MIT"
},
+ "node_modules/preact": {
+ "version": "10.25.4",
+ "resolved": "https://registry.npmjs.org/preact/-/preact-10.25.4.tgz",
+ "integrity": "sha512-jLdZDb+Q+odkHJ+MpW/9U5cODzqnB+fy2EiHSZES7ldV5LK7yjlVzTp7R8Xy6W6y75kfK8iWYtFVH7lvjwrCMA==",
+ "license": "MIT",
+ "peer": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ }
+ },
"node_modules/prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
diff --git a/package.json b/package.json
index 2761696..310523f 100644
--- a/package.json
+++ b/package.json
@@ -11,12 +11,18 @@
},
"dependencies": {
"@radix-ui/react-checkbox": "^1.1.4",
+ "@radix-ui/react-context-menu": "^2.2.6",
"@radix-ui/react-dialog": "^1.1.6",
"@radix-ui/react-label": "^2.1.2",
"@radix-ui/react-separator": "^1.1.2",
"@radix-ui/react-slot": "^1.1.2",
"@radix-ui/react-tabs": "^1.1.3",
"@radix-ui/react-tooltip": "^1.1.8",
+ "@schedule-x/drag-and-drop": "^2.19.0",
+ "@schedule-x/events-service": "^2.19.0",
+ "@schedule-x/react": "^2.19.0",
+ "@schedule-x/theme-shadcn": "^2.19.0",
+ "@types/react-big-calendar": "^1.16.1",
"axios": "^1.7.9",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
diff --git a/src/app/api/account/route.ts b/src/app/api/account/route.ts
index 9ae5063..88f2ec7 100644
--- a/src/app/api/account/route.ts
+++ b/src/app/api/account/route.ts
@@ -1,10 +1,5 @@
import { NextResponse, NextRequest } from 'next/server';
-import { TwitterApi } from 'twitter-api-v2';
-import config from '@/app/api/env';
-import { PostRequest } from '@/utils';
-import { inspect } from 'util';
import database from '../database';
-import { generateUrlSafeString } from '@/utils';
// Account creation
// Email doesn't exist
diff --git a/src/app/api/database.ts b/src/app/api/database.ts
index e65f5c9..81758f0 100644
--- a/src/app/api/database.ts
+++ b/src/app/api/database.ts
@@ -1,6 +1,6 @@
import { MongoClient } from 'mongodb';
import config from './env';
-import { generateUrlSafeString, Session, User } from '@/utils';
+import { Session, User } from '@/utils';
const client = new MongoClient(config.mongoUrl);
diff --git a/src/app/api/posts/route.ts b/src/app/api/posts/route.ts
index 48b5455..fe15cd3 100644
--- a/src/app/api/posts/route.ts
+++ b/src/app/api/posts/route.ts
@@ -20,6 +20,14 @@ export async function POST(req: NextRequest) {
});
await twitterClient.v2.tweet(content);
+
+ default:
+ return NextResponse.json(
+ {
+ message: 'Not implemented',
+ },
+ { status: 501 }
+ );
}
}
} catch (err) {
diff --git a/src/app/calendar/page.tsx b/src/app/calendar/page.tsx
new file mode 100644
index 0000000..e907ee4
--- /dev/null
+++ b/src/app/calendar/page.tsx
@@ -0,0 +1,115 @@
+'use client';
+import { useCalendarApp, ScheduleXCalendar } from '@schedule-x/react';
+import {
+ createViewDay,
+ createViewMonthAgenda,
+ createViewMonthGrid,
+ createViewWeek,
+} from '@schedule-x/calendar';
+
+import { createEventsServicePlugin } from '@schedule-x/events-service';
+import { createDragAndDropPlugin } from '@schedule-x/drag-and-drop';
+
+import '@/calendar-theme.css';
+import { useEffect, useState } from 'react';
+import App from '@/components/app';
+import {
+ ContextMenu,
+ ContextMenuContent,
+ ContextMenuItem,
+ ContextMenuTrigger,
+} from '@/components/ui/context-menu';
+
+import { PlusCircle } from 'lucide-react';
+import {
+ Dialog,
+ DialogContent,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+} from '@/components/ui/dialog';
+import { Button } from '@/components/ui/button';
+
+function CalendarApp() {
+ const eventsService = useState(() => createEventsServicePlugin())[0];
+ const dragAndDrop = useState(() => createDragAndDropPlugin())[0];
+
+ const calendar = useCalendarApp({
+ views: [
+ createViewDay(),
+ createViewWeek(),
+ createViewMonthGrid(),
+ createViewMonthAgenda(),
+ ],
+ events: [
+ {
+ id: '1',
+ title: 'Linus tech tips drama',
+ start: '2025-02-16 01:00',
+ end: '2025-02-16 02:00',
+ },
+ ],
+ plugins: [eventsService, dragAndDrop],
+ isDark: true,
+ });
+
+ useEffect(() => {
+ console.log(eventsService.getAll());
+ }, [eventsService]);
+
+ const [newPostDialogOpen, setNewPostDialogOpen] = useState(false);
+
+ return (
+
+
+
+
+
+
+
+
+
+ {
+ setNewPostDialogOpen(true);
+ }}
+ >
+ {' '}
+ New post
+
+
+
+
+
+ );
+}
+
+function CalendarHeader() {
+ return
;
+}
+
+export default CalendarApp;
diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx
index 351b0a0..98bc097 100644
--- a/src/app/dashboard/page.tsx
+++ b/src/app/dashboard/page.tsx
@@ -2,25 +2,12 @@ import AccountStatus from '@/components/accountStatus';
import Engagement from '@/components/engagement';
import Ideas from '@/components/ideas';
import RecentPosts from '@/components/recentPosts';
+import App from '@/components/app';
import { Calendar } from '@/components/ui/calendar';
-import {
- SidebarProvider,
- Sidebar,
- SidebarContent,
-} from '@/components/ui/sidebar';
-
export default function Dashboard() {
return (
-
-
-
-
- Hello
-
-
-
-
+
Dashboard
@@ -103,6 +90,6 @@ export default function Dashboard() {
/>
-
+
);
}
diff --git a/src/calendar-theme.css b/src/calendar-theme.css
new file mode 100644
index 0000000..cdbeadc
--- /dev/null
+++ b/src/calendar-theme.css
@@ -0,0 +1,1279 @@
+/*
+Some portions of this code were copied from the shadcn-ui project. The original code is licensed under the MIT License.
+Copyright notice below copied from: https://github.com/shadcn-ui/ui
+________________________________________________________________________
+MIT License
+
+Copyright (c) 2023 shadcn
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+:root {
+ --sx-color-primary: #6750a4;
+ --sx-color-on-primary: #fff;
+ --sx-color-primary-container: #eaddff;
+ --sx-color-on-primary-container: #21005e;
+ --sx-color-secondary: #625b71;
+ --sx-color-on-secondary: #fff;
+ --sx-color-secondary-container: #e8def8;
+ --sx-color-on-secondary-container: #1e192b;
+ --sx-color-tertiary: #7d5260;
+ --sx-color-on-tertiary: #fff;
+ --sx-color-tertiary-container: #ffd8e4;
+ --sx-color-on-tertiary-container: #370b1e;
+ --sx-color-surface: #fef7ff;
+ --sx-color-surface-dim: #ded8e1;
+ --sx-color-surface-bright: #fef7ff;
+ --sx-color-on-surface: #1c1b1f;
+ --sx-color-surface-container: #f3edf7;
+ --sx-color-surface-container-low: #f7f2fa;
+ --sx-color-surface-container-high: #ece6f0;
+ --sx-color-background: #fff;
+ --sx-color-on-background: #1c1b1f;
+ --sx-color-outline: #79747e;
+ --sx-color-outline-variant: #c4c7c5;
+ --sx-color-shadow: #000;
+ --sx-color-surface-tint: #6750a4;
+ --sx-color-neutral: var(--sx-color-outline);
+ --sx-color-neutral-variant: var(--sx-color-outline-variant);
+ --sx-internal-color-gray-ripple-background: #e0e0e0;
+ --sx-internal-color-light-gray: #fafafa;
+ --sx-internal-color-text: #000;
+}
+
+.is-dark {
+ --sx-color-primary: #d0bcff;
+ --sx-color-on-primary: #371e73;
+ --sx-color-primary-container: #4f378b;
+ --sx-color-on-primary-container: #eaddff;
+ --sx-color-secondary: #ccc2dc;
+ --sx-color-on-secondary: #332d41;
+ --sx-color-secondary-container: #4a4458;
+ --sx-color-on-secondary-container: #e8def8;
+ --sx-color-tertiary: #efb8c8;
+ --sx-color-on-tertiary: #492532;
+ --sx-color-tertiary-container: #633b48;
+ --sx-color-on-tertiary-container: #ffd8e4;
+ --sx-color-surface: #141218;
+ --sx-color-surface-dim: #141218;
+ --sx-color-surface-bright: #3b383e;
+ --sx-color-on-surface: #e6e1e5;
+ --sx-color-surface-container: #211f26;
+ --sx-color-surface-container-low: #1d1b20;
+ --sx-color-surface-container-high: #2b2930;
+ --sx-color-background: #141218;
+ --sx-color-on-background: #e6e1e5;
+ --sx-color-outline: #938f99;
+ --sx-color-outline-variant: #444746;
+ --sx-color-shadow: #000;
+ --sx-color-surface-tint: #d0bcff;
+ --sx-internal-color-text: #fff;
+}
+
+:root {
+ --sx-spacing-padding1: 4px;
+ --sx-spacing-padding2: 8px;
+ --sx-spacing-padding3: 12px;
+ --sx-spacing-padding4: 16px;
+ --sx-spacing-padding6: 24px;
+ --sx-spacing-modal-padding: 16px;
+}
+
+:root {
+ --sx-box-shadow-level3: 0 3px 6px 0 rgb(0 0 0 / 16%),
+ 0 3px 6px 0 rgb(0 0 0 / 23%);
+ --sx-rounding-extra-small: 4px;
+ --sx-rounding-small: 8px;
+ --sx-rounding-extra-large: 28px;
+ --sx-border: 1px solid var(--sx-color-outline-variant);
+}
+
+.is-dark {
+ --sx-border: 1px solid var(--sx-color-outline-variant);
+}
+
+:root {
+ --sx-font-small: 0.875rem;
+ --sx-font-extra-small: 0.75rem;
+ --sx-font-large: 1.125rem;
+ --sx-font-extra-large: 1.25rem;
+}
+
+:root {
+ --sx-calendar-header-input-font-size: clamp(12px, 0.875rem, 28px);
+ --sx-calendar-header-popup-z-index: 3;
+ --sx-calendar-week-grid-padding-left: 75px;
+}
+:root .sx__date-picker-popup.is-teleported {
+ z-index: 3;
+}
+
+@keyframes sx-ripple {
+ 0% {
+ width: 0;
+ height: 0;
+ opacity: 0.16;
+ }
+ 40% {
+ width: 100px;
+ height: 100px;
+ opacity: 0.08;
+ }
+ 100% {
+ width: 150px;
+ height: 150px;
+ opacity: 0;
+ }
+}
+
+.sx__ripple {
+ position: relative;
+ overflow: hidden;
+}
+.sx__ripple::before {
+ content: '';
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 0;
+ height: 0;
+ transform: translate(-50%, -50%);
+ border-radius: 50%;
+ background-color: currentcolor;
+ opacity: 0.1;
+ visibility: hidden;
+ z-index: 2;
+}
+.sx__ripple:active::before {
+ visibility: visible;
+}
+.sx__ripple:not(:active)::before {
+ animation: sx-ripple 0.75s cubic-bezier(0, 0.1, 0.8, 1);
+ transition: visibility 0.75s step-end;
+}
+
+@keyframes sx-ripple-wide {
+ 0% {
+ width: 0;
+ height: 0;
+ opacity: 0.16;
+ }
+ 40% {
+ width: 300px;
+ height: 100px;
+ opacity: 0.08;
+ }
+ 100% {
+ width: 450px;
+ height: 150px;
+ opacity: 0;
+ }
+}
+.sx__ripple--wide {
+ position: relative;
+ overflow: hidden;
+}
+.sx__ripple--wide::before {
+ content: '';
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 0;
+ height: 0;
+ transform: translate(-50%, -50%);
+ border-radius: 50%;
+ background-color: currentcolor;
+ opacity: 0.1;
+ visibility: hidden;
+ z-index: 2;
+}
+.sx__ripple--wide:active::before {
+ visibility: visible;
+}
+.sx__ripple--wide::before {
+ border-radius: var(--sx-rounding-small);
+}
+.sx__ripple--wide:not(:active)::before {
+ animation: sx-ripple-wide 0.75s cubic-bezier(0, 0.1, 0.8, 1);
+ transition: visibility 0.75s step-end;
+}
+
+.sx__chevron-wrapper {
+ position: relative;
+ border-radius: 50%;
+ min-height: 48px;
+ min-width: 48px;
+ cursor: pointer;
+ transition: background-color 0.2s ease-in-out;
+ font-size: 0;
+}
+.sx__chevron-wrapper:active {
+ background-color: var(--sx-internal-color-gray-ripple-background);
+}
+.sx__chevron-wrapper:disabled {
+ cursor: not-allowed;
+ opacity: 0.5;
+}
+.sx__chevron-wrapper:hover,
+.sx__chevron-wrapper:focus {
+ background-color: var(--sx-color-surface-dim);
+}
+.is-dark .sx__chevron-wrapper:hover,
+.is-dark .sx__chevron-wrapper:focus {
+ background-color: var(--sx-color-surface-container-high);
+}
+.sx__chevron-wrapper .sx__chevron {
+ position: absolute;
+ top: 50%;
+ width: 0.6rem;
+ height: 0.6rem;
+ border-width: 0.2rem 0.2rem 0 0;
+ border-style: solid;
+ border-color: var(--sx-internal-color-text);
+}
+
+.sx__chevron--previous {
+ left: calc(50% + 0.125rem);
+ transform: translate(-50%, -50%) rotate(225deg);
+}
+
+.sx__chevron--next {
+ left: calc(50% - 0.125rem);
+ transform: translate(-50%, -50%) rotate(45deg);
+}
+
+.sx__date-picker-wrapper {
+ position: relative;
+ color: var(--sx-color-on-background);
+ width: fit-content;
+}
+.sx__date-picker-wrapper.has-full-width {
+ width: 100%;
+}
+.sx__date-picker-wrapper.is-disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+.sx__date-picker-wrapper * {
+ color: var(--sx-color-on-background);
+ box-sizing: border-box;
+}
+
+.sx__date-input-wrapper {
+ position: relative;
+}
+
+.sx__date-input-chevron-wrapper {
+ position: absolute;
+ top: 50%;
+ right: 1rem;
+ transform: translateY(-50%);
+ display: flex;
+ align-items: center;
+ padding: 0;
+ transition: transform 0.2s ease-in-out;
+}
+.sx__date-input-chevron-wrapper:focus {
+ border: 2px solid var(--sx-color-primary);
+}
+.is-disabled .sx__date-input-chevron-wrapper {
+ pointer-events: none;
+ cursor: not-allowed;
+}
+.sx__date-input--active .sx__date-input-chevron-wrapper {
+ transform: translateY(-50%) rotate(180deg);
+}
+
+.sx__date-input-chevron {
+ width: 1rem;
+ height: 1rem;
+ pointer-events: none;
+}
+
+.sx__date-input {
+ font-size: 1rem;
+ padding: var(--sx-spacing-padding4);
+ border: var(--sx-border);
+ border-radius: var(--sx-rounding-extra-small);
+ cursor: pointer;
+ background-color: var(--sx-color-background);
+ width: 100%;
+}
+.is-disabled .sx__date-input {
+ pointer-events: none;
+}
+.sx__date-input--active .sx__date-input {
+ border-color: var(--sx-color-primary);
+ outline: 1px solid var(--sx-color-primary);
+}
+
+.sx__date-input-label {
+ position: absolute;
+ top: 0;
+ left: 21px;
+ padding: 0 var(--sx-spacing-padding1);
+ background-color: var(--sx-color-background);
+ font-size: 0.75rem;
+ color: var(--sx-color-neutral);
+ line-height: 1rem;
+ transform: translateY(-50%) translateX(-0.5rem);
+ transition: transform 0.2s ease-in-out;
+ pointer-events: none;
+}
+.sx__date-input--active .sx__date-input-label {
+ color: var(--sx-color-primary);
+}
+.is-dark .sx__date-input-label {
+ display: none;
+}
+
+.sx__date-picker-popup {
+ position: absolute;
+ height: fit-content;
+ z-index: 1;
+ top: calc(100% + 1px);
+ width: 20.75rem;
+ max-width: 500px;
+ max-height: 400px;
+ overflow: scroll;
+ box-shadow: var(--sx-box-shadow-level3);
+ padding: var(--sx-spacing-modal-padding);
+ background-color: var(--sx-color-background);
+ color: var(--sx-internal-color-text);
+}
+.sx__date-picker-popup.is-dark {
+ background-color: var(--sx-color-surface-container-high);
+}
+.sx__date-picker-popup.bottom-end {
+ left: auto;
+ right: 0;
+ transform: translateX(0);
+}
+.sx__date-picker-popup.top-start {
+ inset: auto auto calc(100% + 1rem) 0;
+ transform: translateX(0);
+}
+.sx__date-picker-popup.top-end {
+ inset: auto 0 calc(100% + 1rem) auto;
+ transform: translateX(0);
+}
+
+.sx__date-picker__years-view {
+ margin: 0;
+}
+
+.sx__date-picker__years-accordion__expand- {
+ width: 100%;
+ border-radius: 0;
+ background-color: transparent;
+ font-size: 1rem;
+ padding: 1em;
+ transition: background-color 0.2s ease-in-out;
+ color: var(--sx-internal-color-text);
+}
+.sx__is-expanded .sx__date-picker__years-accordion__expand- {
+ background-color: var(--sx-color-surface-container);
+}
+.sx__date-picker__years-accordion__expand-:hover {
+ background-color: var(--sx-color-surface-dim);
+}
+.sx__date-picker__years-accordion__expand-:active {
+ background-color: var(--sx-internal-color-gray-ripple-background);
+}
+
+.sx__date-picker__years-view-accordion__panel {
+ display: flex;
+ flex-wrap: wrap;
+}
+
+.sx__date-picker__years-view-accordion__month {
+ flex: 1 0 33.3333%;
+ background-color: transparent;
+ border: 0;
+ font-size: 0.9rem;
+ padding: 0.5em 0;
+ border-radius: 25px;
+ color: var(--sx-internal-color-text);
+}
+.sx__date-picker__years-view-accordion__month:hover {
+ background-color: var(--sx-color-primary);
+ color: var(--sx-color-on-primary);
+}
+
+.sx__date-picker__day-names {
+ display: flex;
+ width: 100%;
+ justify-content: space-evenly;
+ margin-bottom: 0.5em;
+}
+.sx__date-picker__day-names .sx__date-picker__day,
+.sx__date-picker__day-names .sx__date-picker__day-name {
+ flex: 1;
+ text-align: center;
+}
+
+.sx__date-picker__day-name {
+ font-weight: 700;
+ color: var(--sx-color-neutral-variant);
+}
+
+.sx__date-picker__month-view-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 1em;
+}
+.sx__date-picker__month-view-header .sx__chevron-wrapper:hover {
+ background-color: var(--sx-color-surface-dim);
+}
+
+.sx__date-picker__month-view-header__month-year {
+ font-size: 1.5rem;
+ font-weight: 300;
+ color: var(--sx-internal-color-text);
+}
+.sx__date-picker__month-view-header__month-year:hover {
+ color: var(--sx-color-primary);
+ text-decoration: underline;
+}
+
+.sx__date-picker__week {
+ display: flex;
+ width: 100%;
+ justify-content: space-evenly;
+ margin-bottom: 0.5em;
+}
+.sx__date-picker__week .sx__date-picker__day,
+.sx__date-picker__week .sx__date-picker__day-name {
+ flex: 1;
+ text-align: center;
+}
+
+.sx__date-picker__day {
+ background-color: transparent;
+ border-radius: 50%;
+ width: 2.5rem;
+ height: 2.5rem;
+ color: var(--sx-internal-color-text);
+}
+.sx__date-picker__day:hover {
+ background-color: var(--sx-color-surface-dim);
+}
+.sx__date-picker__day:focus {
+ outline-offset: -2px;
+ outline: 2px solid var(--sx-color-primary);
+}
+.sx__date-picker__day:disabled {
+ color: var(--sx-color-neutral-variant);
+ cursor: not-allowed;
+}
+.sx__date-picker__day.is-leading-or-trailing {
+ color: var(--sx-color-neutral-variant);
+}
+.sx__date-picker__day.sx__date-picker__day--selected {
+ background-color: var(--sx-color-primary-container);
+ color: var(--sx-color-on-primary-container);
+}
+.sx__date-picker__day.sx__date-picker__day--today {
+ background-color: var(--sx-color-primary);
+ color: var(--sx-color-on-primary);
+}
+
+.sx__calendar-wrapper {
+ height: 100%;
+ display: flex;
+ color: var(--sx-internal-color-text);
+}
+.sx__calendar-wrapper * {
+ box-sizing: border-box;
+}
+
+.sx__calendar {
+ position: relative;
+ flex: 1;
+ height: 100%;
+ border: var(--sx-border);
+ border-radius: var(--sx-rounding-small);
+ display: flex;
+ flex-flow: column;
+ background-color: var(--sx-color-background);
+ overflow: hidden;
+}
+
+.sx__view-container {
+ position: relative;
+ flex: 1;
+ overflow-y: auto;
+ scroll-behavior: smooth;
+}
+
+.sx__slide-left {
+ animation: sx-slide-left 0.3s ease-out;
+}
+
+@keyframes sx-slide-left {
+ 0% {
+ transform: translateX(8%);
+ filter: blur(0.25rem);
+ opacity: 0.1;
+ }
+ 100% {
+ transform: translateX(0);
+ filter: blur(0);
+ opacity: 1;
+ }
+}
+.sx__slide-right {
+ animation: sx-slide-right 0.3s ease-out;
+}
+
+@keyframes sx-slide-right {
+ 0% {
+ transform: translateX(-8%);
+ filter: blur(0.25rem);
+ opacity: 0.1;
+ }
+ 100% {
+ transform: translateX(0);
+ filter: blur(0);
+ opacity: 1;
+ }
+}
+.sx__calendar-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ padding: var(--sx-spacing-padding4);
+ gap: var(--sx-spacing-padding4);
+}
+.sx__calendar-header .sx__date-input {
+ padding: var(--sx-spacing-padding3) var(--sx-spacing-padding4);
+ font-size: var(--sx-calendar-header-input-font-size);
+}
+.sx__calendar-header .sx__date-picker-popup {
+ z-index: var(--sx-calendar-header-popup-z-index);
+}
+
+.sx__calendar-header-content {
+ display: flex;
+ align-items: center;
+ gap: var(--sx-spacing-padding4);
+}
+
+.sx__forward-backward-navigation {
+ height: 45px;
+}
+.sx__is-calendar-small .sx__forward-backward-navigation {
+ display: none;
+}
+
+.sx__range-heading {
+ font-size: clamp(16px, 1.25rem, 24px);
+}
+.sx__is-calendar-small .sx__range-heading {
+ font-size: 16px;
+}
+
+.sx__today- {
+ padding: var(--sx-spacing-padding3) var(--sx-spacing-padding4);
+ border-radius: var(--sx-rounding-extra-small);
+ font-size: var(--sx-calendar-header-input-font-size);
+ color: var(--sx-internal-color-text);
+}
+.sx__today-:active {
+ background-color: var(--sx-internal-color-gray-ripple-background);
+}
+.sx__is-calendar-small .sx__today- {
+ display: none;
+}
+.sx__calendar-header .sx__today- {
+ border: var(--sx-border);
+}
+.sx__today-:hover,
+.sx__today-:focus {
+ background-color: var(--sx-internal-color-light-gray);
+}
+.is-dark .sx__today-:hover,
+.is-dark .sx__today-:focus {
+ background-color: var(--sx-color-surface-container-low);
+}
+
+.sx__view-selection {
+ position: relative;
+ font-size: var(--sx-calendar-header-input-font-size);
+}
+
+.sx__view-selection-selected-item {
+ height: 100%;
+ width: fit-content;
+ padding: var(--sx-spacing-padding3) var(--sx-spacing-padding4);
+ cursor: pointer;
+ border-radius: var(--sx-rounding-extra-small);
+ border: var(--sx-border);
+}
+.sx__view-selection-selected-item:hover {
+ background-color: var(--sx-internal-color-light-gray);
+}
+.is-dark .sx__view-selection-selected-item:hover {
+ background-color: var(--sx-color-surface-container-low);
+}
+
+.sx__view-selection-items {
+ position: absolute;
+ top: 100%;
+ box-shadow: var(--sx-box-shadow-level3);
+ margin: 0;
+ background-color: var(--sx-color-background);
+ z-index: var(--sx-calendar-header-popup-z-index);
+}
+.is-dark .sx__view-selection-items {
+ background-color: var(--sx-color-surface-container-high);
+}
+
+.sx__view-selection-item {
+ padding: var(--sx-spacing-padding4) var(--sx-spacing-padding6);
+ cursor: pointer;
+}
+.sx__view-selection-item:hover,
+.sx__view-selection-item:focus {
+ background-color: var(--sx-color-primary);
+ color: var(--sx-color-on-primary);
+}
+.sx__view-selection-item.is-selected {
+ background-color: var(--sx-color-surface-dim);
+}
+.sx__view-selection-item.is-selected:hover,
+.sx__view-selection-item.is-selected:focus {
+ background-color: var(--sx-color-primary);
+ color: var(--sx-color-on-primary);
+}
+
+.sx__month-grid-wrapper {
+ display: flex;
+ flex-flow: column;
+ height: 100%;
+}
+
+.sx__month-grid-week {
+ border-top: var(--sx-border);
+ flex: 1;
+ display: flex;
+}
+
+.sx__month-grid-day {
+ position: relative;
+ padding: var(--sx-spacing-padding2) 0;
+ flex: 1;
+}
+.sx__month-grid-day:not(:last-child) {
+ border-right: var(--sx-border);
+}
+
+.sx__month-grid-day--dragover {
+ background-color: var(--sx-color-surface-container);
+}
+
+.sx__month-grid-day__header {
+ display: flex;
+ flex-flow: column;
+ align-items: center;
+}
+
+.sx__month-grid-day__header-day-name {
+ font-size: 11px;
+ text-transform: uppercase;
+ color: var(--sx-color-neutral);
+}
+
+.sx__month-grid-day__header-date {
+ font-size: var(--sx-font-extra-small);
+ margin-bottom: var(--sx-spacing-padding1);
+ border-radius: 50%;
+ height: 24px;
+ width: 24px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+.sx__month-grid-day__header-date.sx__is-today {
+ background-color: var(--sx-color-primary);
+ color: var(--sx-color-on-primary);
+}
+
+.sx__month-grid-day__events-more {
+ width: calc(100% - 10px);
+ font-size: var(--sx-font-extra-small);
+ color: var(--sx-color-neutral);
+ margin: var(--sx-spacing-padding1) 0;
+ padding: var(--sx-spacing-padding1);
+ border-radius: var(--sx-rounding-extra-small);
+ cursor: pointer;
+ transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;
+}
+.sx__month-grid-day__events-more:hover {
+ background-color: var(--sx-color-surface-container);
+ color: var(--sx-color-on-surface);
+}
+
+.sx__month-grid-background-event {
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 100%;
+ width: 100%;
+}
+
+.sx__month-grid-day__events {
+ display: grid;
+ grid-gap: 4px;
+}
+
+.sx__month-grid-cell {
+ height: clamp(20px, 1.25rem, 24px);
+}
+
+.sx__month-grid-event {
+ position: relative;
+ display: flex;
+ align-items: center;
+ padding: var(--sx-spacing-padding1);
+ border-radius: var(--sx-rounding-extra-small);
+ font-size: clamp(12px, var(--sx-font-extra-small), 14px);
+ overflow: hidden;
+ white-space: nowrap;
+ z-index: 1;
+}
+
+.sx__month-grid-event-time {
+ margin-right: 4px;
+}
+
+.sx__month-grid-blocker {
+ pointer-events: none;
+}
+
+.sx__month-agenda-week {
+ display: flex;
+}
+.sx__month-agenda-week:not(:first-child) {
+ border-top: var(--sx-border);
+}
+
+.sx__month-agenda-day {
+ padding: var(--sx-spacing-padding2);
+ flex: 1;
+ display: flex;
+ flex-flow: column;
+ align-items: center;
+ height: 3rem;
+ border-radius: var(--sx-rounding-extra-small);
+}
+
+.sx__month-agenda-day--active {
+ box-shadow: inset 0 0 0 3px var(--sx-color-primary);
+}
+
+.sx__month-agenda-day__event-icons {
+ margin-top: 4px;
+ display: flex;
+ grid-gap: 3px;
+}
+
+.sx__month-agenda-day__event-icon {
+ height: 6px;
+ width: 6px;
+ border-radius: 50%;
+}
+
+.sx__month-agenda-day-names {
+ display: flex;
+ padding: var(--sx-spacing-padding2) 0;
+ font-size: var(--sx-font-extra-small);
+ color: var(--sx-color-neutral);
+}
+
+.sx__month-agenda-day-name {
+ flex: 1;
+ display: flex;
+ justify-content: center;
+}
+
+.sx__month-agenda-events {
+ padding: 0 var(--sx-spacing-padding2);
+}
+
+.sx__month-agenda-event {
+ padding: var(--sx-spacing-padding2);
+ margin-bottom: var(--sx-spacing-padding2);
+ border-radius: var(--sx-rounding-extra-small);
+ font-size: var(--sx-font-small);
+}
+.sx__month-agenda-event:first-child {
+ margin-top: var(--sx-spacing-padding2);
+}
+
+.sx__month-agenda-event__title {
+ font-weight: 600;
+}
+
+.sx__month-agenda-event__has-icon {
+ display: flex;
+ align-items: center;
+}
+
+.sx__month-agenda-events__empty {
+ margin-top: var(--sx-spacing-padding4);
+ display: flex;
+ justify-content: center;
+}
+
+.sx__week-wrapper {
+ position: relative;
+}
+
+.sx__week-grid {
+ position: relative;
+ padding-left: var(--sx-calendar-week-grid-padding-left);
+ display: flex;
+ height: var(--sx-week-grid-height);
+ overflow: hidden;
+}
+
+.sx__week-header {
+ position: sticky;
+ top: 0;
+ z-index: 2;
+ background-color: var(--sx-color-background);
+}
+
+.sx__week-header-content {
+ position: relative;
+}
+
+.sx__week-header-border {
+ position: absolute;
+ width: 100%;
+ bottom: 0;
+ border-bottom: var(--sx-border);
+ border-left: 250px solid transparent;
+}
+
+.sx__week-grid__time-axis {
+ display: flex;
+ flex-flow: column;
+ position: absolute;
+ right: 0;
+ top: var(--sx-week-grid-offset-top);
+ width: calc(100% - 60px);
+}
+
+.sx__week-grid__hour {
+ position: relative;
+ height: var(--sx-week-grid-hour-height);
+ border-top: var(--sx-border);
+ font-size: var(--sx-font-extra-small);
+}
+.sx__week-grid__hour:first-child {
+ visibility: hidden;
+}
+
+.sx__week-grid__hour-text {
+ position: absolute;
+ left: -43px;
+ top: -0.75em;
+ color: var(--sx-color-neutral);
+}
+
+.sx__time-grid-day {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ border-left: var(--sx-border);
+}
+
+.sx__week-grid__date-axis {
+ padding-left: var(--sx-calendar-week-grid-padding-left);
+ display: flex;
+}
+
+.sx__week-grid__date {
+ flex: 1;
+ display: flex;
+ flex-flow: column;
+ align-items: center;
+ padding: var(--sx-spacing-padding3) 0;
+ gap: var(--sx-spacing-padding1);
+}
+
+.sx__week-grid__day-name {
+ text-transform: uppercase;
+ font-size: var(--sx-font-extra-small);
+ color: var(--sx-color-neutral);
+ font-weight: 500;
+}
+.sx__week-grid__date--is-today .sx__week-grid__day-name {
+ color: var(--sx-color-primary);
+ font-weight: 700;
+}
+
+.sx__week-grid__date-number {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: var(--sx-font-extra-large);
+ font-weight: 500;
+ color: var(--sx-color-neutral);
+ height: 2em;
+ width: 2em;
+}
+.sx__week-grid__date--is-today .sx__week-grid__date-number {
+ background-color: var(--sx-color-primary);
+ color: var(--sx-color-on-primary);
+ border-radius: 50%;
+}
+
+.sx__time-grid-event {
+ width: calc(100% - 10px);
+ padding: var(--sx-spacing-padding1);
+ position: absolute;
+ border-radius: var(--sx-rounding-extra-small);
+ font-size: var(--sx-font-extra-small);
+ overflow: hidden;
+ -webkit-user-select: none;
+ user-select: none;
+}
+.sx__time-grid-event.is-event-copy {
+ opacity: 0.5;
+ box-shadow: var(--sx-box-shadow-level3);
+ z-index: 1;
+ transition: transform 0.15s ease-in-out;
+}
+
+[data-has-dnd='true'] .sx__time-grid-event {
+ touch-action: none;
+}
+
+.sx__is-resizing .sx__time-grid-event:has(+ .is-event-copy) {
+ opacity: 0;
+}
+.sx__is-resizing .is-event-copy {
+ opacity: 1;
+}
+
+.sx__time-grid-event-inner {
+ position: relative;
+ height: 100%;
+}
+
+.sx__time-grid-event-resize-handle {
+ display: none;
+}
+
+/** Only display the resize handle on non-touch devices */
+@media (hover: hover) {
+ .sx__time-grid-event-resize-handle {
+ display: block;
+ position: absolute;
+ width: 100%;
+ bottom: 0;
+ cursor: ns-resize;
+ height: clamp(10px, 20px, 50%);
+ }
+}
+.sx__time-grid-event-title {
+ font-weight: 600;
+}
+
+.sx__time-grid-event-time,
+.sx__time-grid-event-people,
+.sx__time-grid-event-location {
+ display: flex;
+ align-items: center;
+ white-space: nowrap;
+}
+
+.sx__event-icon {
+ min-width: 15px;
+ min-height: 15px;
+ max-width: 15px;
+ max-height: 15px;
+ margin-inline-end: var(--sx-spacing-padding2);
+}
+
+.sx__date-grid {
+ display: flex;
+ padding-left: var(--sx-calendar-week-grid-padding-left);
+}
+
+.sx__date-grid-day {
+ position: relative;
+ width: 100%;
+ display: grid;
+ grid-gap: 2px;
+ /* needed for the draw plugin */
+}
+.sx__date-grid-day .sx__spacer {
+ display: var(--sx-draw-plugin-spacer-display, none);
+ height: var(--sx-draw-plugin-spacer);
+}
+
+.sx__date-grid-event {
+ z-index: 1;
+ position: relative;
+ display: flex;
+ align-items: center;
+ padding: var(--sx-spacing-padding1);
+ border-radius: var(--sx-rounding-extra-small);
+ font-size: clamp(12px, var(--sx-font-extra-small), 14px);
+ font-weight: 600;
+ user-select: none;
+}
+.sx__date-grid-event:has(.sx__date-grid-event--left-overflow) {
+ margin-left: 10px;
+}
+.sx__date-grid-event:has(.sx__date-grid-event--right-overflow) {
+ margin-right: 10px;
+}
+.sx__date-grid-event .sx__date-grid-event--left-overflow {
+ position: absolute;
+ z-index: 1;
+ width: 10px;
+ height: 100%;
+ left: -10px;
+ clip-path: polygon(100% 0, 0 50%, 100% 100%, 100% 0);
+}
+.sx__date-grid-event .sx__date-grid-event--right-overflow {
+ position: absolute;
+ z-index: 1;
+ width: 10px;
+ height: 100%;
+ right: -10px;
+ clip-path: polygon(0 0, 100% 50%, 0 100%, 0 0);
+}
+.sx__date-grid-event.sx__date-grid-event--copy {
+ z-index: 2;
+ box-shadow: var(--sx-box-shadow-level3);
+ transition-property: transform, width;
+ transition-duration: 0.15s;
+ transition-timing-function: ease-in-out;
+}
+
+.sx__date-grid-event-text {
+ width: calc(100% - var(--sx-spacing-padding1) * 2);
+ left: var(--sx-spacing-padding1);
+ position: absolute;
+ text-overflow: ellipsis;
+ overflow-x: hidden;
+ white-space: nowrap;
+}
+.sx__date-grid-event-text .sx__date-grid-event-time {
+ font-weight: initial;
+}
+
+.sx__date-grid-cell {
+ height: clamp(20px, 1.25rem, 24px);
+}
+
+.sx__date-grid-event-resize-handle {
+ position: absolute;
+ right: 0;
+ height: 100%;
+ width: clamp(10px, 15px, 50%);
+ cursor: ew-resize;
+ z-index: 1;
+}
+
+.sx__date-grid-background-event {
+ position: absolute;
+ height: 100%;
+ width: 100%;
+ top: 0;
+ left: 0;
+ z-index: -1;
+}
+
+:root {
+ --sx-week-grid-height: 0;
+ --sx-time-axis-height: 0;
+ --sx-week-grid-hour-height: 0;
+ --sx-week-grid-offset-top: 0;
+}
+
+.sx__event-modal {
+ visibility: hidden;
+ position: fixed;
+ top: var(--sx-event-modal-top);
+ left: var(--sx-event-modal-left);
+ width: 400px;
+ max-width: 100%;
+ height: fit-content;
+ background-color: var(--sx-color-background);
+ z-index: 2;
+}
+.sx__event-modal.is-open {
+ animation: slide-sideways;
+ animation-duration: 0.3s;
+ visibility: initial;
+}
+.is-dark .sx__event-modal {
+ background-color: var(--sx-color-surface-container-high);
+}
+
+.sx__event-modal-default {
+ padding: var(--sx-spacing-padding6);
+ background-color: var(--sx-color-background);
+ box-shadow: 0 24px 38px 3px rgba(0, 0, 0, 0.14),
+ 0 9px 46px 8px rgba(0, 0, 0, 0.12), 0 11px 15px -7px rgba(0, 0, 0, 0.2);
+ border-radius: var(--sx-rounding-small);
+ max-height: 250px;
+ overflow-y: scroll;
+}
+
+@keyframes slide-sideways {
+ from {
+ opacity: 0;
+ transform: translateX(var(--sx-event-modal-animation-start));
+ }
+ to {
+ transform: translateX(0);
+ opacity: 1;
+ }
+}
+.sx__event-modal .sx__event-icon {
+ min-width: 16px;
+ min-height: 16px;
+ max-width: 16px;
+ max-height: 16px;
+ margin-inline-end: var(--sx-spacing-padding2);
+}
+
+.sx__event-modal__color-icon {
+ display: inline-block;
+ width: 16px;
+ height: 16px;
+ border-radius: 25%;
+ margin-right: var(--sx-spacing-padding3);
+}
+
+.sx__has-icon {
+ display: grid;
+ align-items: flex-start;
+ grid-template-columns: 30px 1fr;
+ margin-bottom: var(--sx-spacing-padding2);
+}
+.sx__has-icon .sx__event-icon {
+ margin-top: 2px;
+}
+.sx__has-icon .sx__event-modal__color-icon {
+ margin-top: 4px;
+}
+
+.sx__event-modal__title {
+ font-size: var(--sx-font-large);
+}
+
+.sx__event-modal__time {
+ font-size: var(--sx-font-small);
+}
+
+.sx__current-time-indicator {
+ position: absolute;
+ left: 0;
+ right: 0;
+ height: 2px;
+ background-color: #f00;
+ z-index: 0;
+}
+.sx__current-time-indicator::before {
+ content: '';
+ position: absolute;
+ left: -5px;
+ top: -4px;
+ width: 10px;
+ height: 10px;
+ border-radius: 50%;
+ background-color: #f00;
+}
+
+.sx__current-time-indicator-full-week {
+ width: calc(100% - var(--sx-calendar-week-grid-padding-left));
+ position: absolute;
+ inset: 0 0 0 var(--sx-calendar-week-grid-padding-left);
+ height: 2px;
+ background-color: rgba(255, 0, 0, 0.38);
+}
+
+.is-shadcn .sx__view-selection-items {
+ overflow: hidden;
+ border-radius: var(--sx-rounding-extra-small);
+ border: var(--sx-border);
+}
+.is-shadcn .sx__date-input-label {
+ display: none;
+}
+.is-shadcn .sx__month-grid-event,
+.is-shadcn .sx__time-grid-event,
+.is-shadcn .sx__date-grid-event,
+.is-shadcn .sx__month-agenda-event {
+ border-radius: var(--sx-event-border-radius);
+}
+.is-shadcn .sx__range-heading {
+ font-weight: 600;
+}
+.is-shadcn .sx__week-grid__day-name,
+.is-shadcn .sx__week-grid__date-number {
+ font-weight: 400;
+}
+
+html:has(.is-shadcn) {
+ --sx-box-shadow-level3: rgba(0, 0, 0, 0%) 0px 0px 0px 0px,
+ rgba(0, 0, 0, 0%) 0px 0px 0px 0px, rgba(0, 0, 0, 10%) 0px 4px 6px -1px,
+ rgba(0, 0, 0, 10%) 0px 2px 4px -2px;
+ --sx-color-primary-container: #000;
+ --sx-color-on-primary-container: #fff;
+ --radius: 0.5rem;
+ --sx-rounding-extra-small: calc(var(--radius) - 2px);
+ --sx-color-primary: #000;
+ --sx-event-border-radius: 4px;
+ --sx-color-surface-container: #f1f2f4;
+ --sx-color-surface-dim: hsl(840deg 4.8% 95.9%);
+ --sx-color-popup-border: rgb(228, 228, 231);
+ --sx-border: 1px solid hsl(240deg 5.9% 90%);
+}
+html:has(.is-shadcn) .is-dark {
+ --sx-color-popup-border: hsl(240deg 3.7% 15.9%);
+ --sx-border: 1px solid hsl(240deg 3.7% 15.9%);
+ --sx-color-primary: #fff;
+ --sx-color-primary-container: #fff;
+ --sx-color-on-primary-container: #000;
+ --sx-color-on-primary: #000;
+}
+html:has(.is-shadcn) .sx__date-picker-popup {
+ border: 1px solid var(--sx-color-popup-border);
+ border-radius: var(--sx-rounding-extra-small);
+}
+html:has(.is-shadcn) .sx__date-picker__day {
+ height: 2.25rem;
+ width: 2.25rem;
+ border-radius: var(--sx-rounding-extra-small);
+}
+html:has(.is-shadcn) .sx__date-picker__years-accordion__expand- {
+ border-radius: var(--sx-rounding-extra-small);
+}
+.sx__is-expanded
+ html:has(.is-shadcn)
+ .sx__date-picker__years-accordion__expand- {
+ background-color: var(--sx-color-surface-container);
+}
+html:has(.is-shadcn) .sx__date-picker__years-view-accordion__month {
+ border-radius: var(--sx-rounding-extra-small);
+}
+html:has(.is-shadcn) .sx__date-picker__day--today {
+ background-color: var(--sx-color-surface-container);
+ color: var(--sx-internal-color-text);
+}
diff --git a/src/components/app.tsx b/src/components/app.tsx
new file mode 100644
index 0000000..291e8a0
--- /dev/null
+++ b/src/components/app.tsx
@@ -0,0 +1,73 @@
+import {
+ SidebarContent,
+ SidebarProvider,
+ Sidebar,
+ SidebarGroup,
+ SidebarGroupLabel,
+ SidebarGroupContent,
+ SidebarMenu,
+ SidebarMenuItem,
+ SidebarMenuButton,
+} from '@/components/ui/sidebar';
+
+import { Calendar, LayoutDashboardIcon, Settings } from 'lucide-react';
+import Link from 'next/link';
+
+// Menu items.
+const items = [
+ {
+ title: 'Dashboard',
+ url: '/dashboard',
+ icon: LayoutDashboardIcon,
+ },
+ {
+ title: 'Calendar',
+ url: '/calendar',
+ icon: Calendar,
+ },
+ {
+ title: 'Settings',
+ url: '/settings',
+ icon: Settings,
+ },
+];
+
+export default function App({ children }: { children?: any }) {
+ return (
+
+
+
+
+
+
+
+ Klayrion v0.0.1-alpha.0
+
+
+
+ {items.map((item) => (
+
+
+
+
+
+ {item.title}
+
+
+
+
+ ))}
+
+
+
+
+
+
+
+
{children}
+
+ );
+}
diff --git a/src/components/ui/context-menu.tsx b/src/components/ui/context-menu.tsx
new file mode 100644
index 0000000..f7257a6
--- /dev/null
+++ b/src/components/ui/context-menu.tsx
@@ -0,0 +1,200 @@
+"use client"
+
+import * as React from "react"
+import * as ContextMenuPrimitive from "@radix-ui/react-context-menu"
+import { Check, ChevronRight, Circle } from "lucide-react"
+
+import { cn } from "@/lib/utils"
+
+const ContextMenu = ContextMenuPrimitive.Root
+
+const ContextMenuTrigger = ContextMenuPrimitive.Trigger
+
+const ContextMenuGroup = ContextMenuPrimitive.Group
+
+const ContextMenuPortal = ContextMenuPrimitive.Portal
+
+const ContextMenuSub = ContextMenuPrimitive.Sub
+
+const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup
+
+const ContextMenuSubTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & {
+ inset?: boolean
+ }
+>(({ className, inset, children, ...props }, ref) => (
+
+ {children}
+
+
+))
+ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName
+
+const ContextMenuSubContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+))
+ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName
+
+const ContextMenuContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+))
+ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName
+
+const ContextMenuItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & {
+ inset?: boolean
+ }
+>(({ className, inset, ...props }, ref) => (
+
+))
+ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName
+
+const ContextMenuCheckboxItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, checked, ...props }, ref) => (
+
+
+
+
+
+
+ {children}
+
+))
+ContextMenuCheckboxItem.displayName =
+ ContextMenuPrimitive.CheckboxItem.displayName
+
+const ContextMenuRadioItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+
+
+
+
+
+ {children}
+
+))
+ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName
+
+const ContextMenuLabel = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & {
+ inset?: boolean
+ }
+>(({ className, inset, ...props }, ref) => (
+
+))
+ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName
+
+const ContextMenuSeparator = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+))
+ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName
+
+const ContextMenuShortcut = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => {
+ return (
+
+ )
+}
+ContextMenuShortcut.displayName = "ContextMenuShortcut"
+
+export {
+ ContextMenu,
+ ContextMenuTrigger,
+ ContextMenuContent,
+ ContextMenuItem,
+ ContextMenuCheckboxItem,
+ ContextMenuRadioItem,
+ ContextMenuLabel,
+ ContextMenuSeparator,
+ ContextMenuShortcut,
+ ContextMenuGroup,
+ ContextMenuPortal,
+ ContextMenuSub,
+ ContextMenuSubContent,
+ ContextMenuSubTrigger,
+ ContextMenuRadioGroup,
+}
diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx
new file mode 100644
index 0000000..1647513
--- /dev/null
+++ b/src/components/ui/dialog.tsx
@@ -0,0 +1,122 @@
+"use client"
+
+import * as React from "react"
+import * as DialogPrimitive from "@radix-ui/react-dialog"
+import { X } from "lucide-react"
+
+import { cn } from "@/lib/utils"
+
+const Dialog = DialogPrimitive.Root
+
+const DialogTrigger = DialogPrimitive.Trigger
+
+const DialogPortal = DialogPrimitive.Portal
+
+const DialogClose = DialogPrimitive.Close
+
+const DialogOverlay = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+))
+DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
+
+const DialogContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+
+
+ {children}
+
+
+ Close
+
+
+
+))
+DialogContent.displayName = DialogPrimitive.Content.displayName
+
+const DialogHeader = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => (
+
+)
+DialogHeader.displayName = "DialogHeader"
+
+const DialogFooter = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => (
+
+)
+DialogFooter.displayName = "DialogFooter"
+
+const DialogTitle = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+))
+DialogTitle.displayName = DialogPrimitive.Title.displayName
+
+const DialogDescription = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+))
+DialogDescription.displayName = DialogPrimitive.Description.displayName
+
+export {
+ Dialog,
+ DialogPortal,
+ DialogOverlay,
+ DialogTrigger,
+ DialogClose,
+ DialogContent,
+ DialogHeader,
+ DialogFooter,
+ DialogTitle,
+ DialogDescription,
+}
diff --git a/src/utils.ts b/src/utils.ts
index 1108813..59ddee1 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -1,12 +1,3 @@
-export function generateUrlSafeString(length = 16) {
- const chars =
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
- const array = new Uint8Array(length);
- crypto.getRandomValues(array);
-
- return Array.from(array, (byte) => chars[byte % chars.length]).join('');
-}
-
export type PlatformKind = 'x' | 'linkedin';
export interface Platform {