diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/nodes/calendarBox/CalendarBox.scss | 9 | ||||
-rw-r--r-- | src/client/views/nodes/calendarBox/CalendarBox.tsx | 77 | ||||
-rw-r--r-- | src/server/apis/google/GoogleTasksHandler.ts | 54 |
3 files changed, 131 insertions, 9 deletions
diff --git a/src/client/views/nodes/calendarBox/CalendarBox.scss b/src/client/views/nodes/calendarBox/CalendarBox.scss index 891db9d90..89dc294a5 100644 --- a/src/client/views/nodes/calendarBox/CalendarBox.scss +++ b/src/client/views/nodes/calendarBox/CalendarBox.scss @@ -50,3 +50,12 @@ pointer-events: unset; } } + +.custom-drag-mirror { + transition: none !important; + transform: none !important; +} + +.fc-event-dragging { + opacity: 0 !important; +} diff --git a/src/client/views/nodes/calendarBox/CalendarBox.tsx b/src/client/views/nodes/calendarBox/CalendarBox.tsx index 92b3224e9..a4183a11a 100644 --- a/src/client/views/nodes/calendarBox/CalendarBox.tsx +++ b/src/client/views/nodes/calendarBox/CalendarBox.tsx @@ -298,15 +298,74 @@ export class CalendarBox extends CollectionSubView() { ev.preventDefault(); }); }} + + // for dragging and dropping (mirror) + + eventDragStart={(arg) => { + const mirror = arg.el.cloneNode(true) as HTMLElement; + const rect = arg.el.getBoundingClientRect(); + + mirror.style.position = 'fixed'; + mirror.style.pointerEvents = 'none'; + mirror.style.opacity = '0.8'; + mirror.style.zIndex = '10000'; + mirror.classList.add('custom-drag-mirror'); + mirror.style.width = `${rect.width}px`; + mirror.style.height = `${rect.height}px`; + + document.body.appendChild(mirror); + + const moveListener = (ev: MouseEvent) => { + mirror.style.left = `${ev.clientX}px`; + mirror.style.top = `${ev.clientY}px`; + }; + + window.addEventListener('mousemove', moveListener); + + // hide the actual box + arg.el.style.visibility = 'hidden'; + arg.el.style.opacity = '0'; + + (arg.el as any)._mirrorElement = mirror; + (arg.el as any)._moveListener = moveListener; + }} + + eventDragStop={(arg) => { + const el = arg.el as any; + const mirror = el._mirrorElement; + const moveListener = el._moveListener; + + // show the actual box + el.style.visibility = 'visible'; + el.style.opacity = '1'; + + if (mirror) document.body.removeChild(mirror); + if (moveListener) window.removeEventListener('mousemove', moveListener); + }} + /> ); } render() { + const scale = this._props.ScreenToLocalTransform().Scale; + const scaledWidth = this._props.PanelWidth(); + const scaledHeight = this._props.PanelHeight(); + return ( <div key={this.calendarViewType} className={`calendarBox${this._props.isContentActive() ? '-interactive' : ''}`} + style={{ + width: scaledWidth, + height: scaledHeight, + overflow: 'hidden', + position: 'relative', + }} + ref={r => { + this.createDashEventsTarget(r); + this.fixWheelEvents(r, this._props.isContentActive); + }} onPointerDown={e => { setTimeout( action(() => { @@ -317,17 +376,17 @@ export class CalendarBox extends CollectionSubView() { if (cname.includes('timeGridDay')) this.dataDoc[this.calTypeFieldKey] = 'timeGridDay'; }) ); - }} - style={{ - width: this._props.PanelWidth() / this._props.ScreenToLocalTransform().Scale, - height: this._props.PanelHeight() / this._props.ScreenToLocalTransform().Scale, - transform: `scale(${this._props.ScreenToLocalTransform().Scale})`, - }} - ref={r => { - this.createDashEventsTarget(r); - this.fixWheelEvents(r, this._props.isContentActive); }}> + <div + style={{ + transform: `scale(${scale})`, + transformOrigin: 'top left', + width: scaledWidth / scale, + height: scaledHeight / scale, + }} + > {this.renderCalendar} + </div> </div> ); } diff --git a/src/server/apis/google/GoogleTasksHandler.ts b/src/server/apis/google/GoogleTasksHandler.ts new file mode 100644 index 000000000..a8af86fe2 --- /dev/null +++ b/src/server/apis/google/GoogleTasksHandler.ts @@ -0,0 +1,54 @@ +import express from 'express'; +import { google } from 'googleapis'; +import { GoogleCredentialsLoader } from './CredentialsLoader'; +import User from '../../authentication/DashUserModel'; +import { DashUserModel } from '../../authentication/DashUserModel'; + + +const router = express.Router(); + +router.post('/tasks/create', async (req, res) => { + try { + const { title, notes, due } = req.body; + + // Make sure user is authenticated + if (!req.user) { + return res.status(401).json({ error: 'User not authenticated' }); + } + + // Assuming access token is stored in user model + const user = req.user as typeof User; // replace with your actual User type if needed + const accessToken = user.googleAccessToken; // <-- change this based on where you store it + + if (!accessToken) { + return res.status(400).json({ error: 'Google access token not found for user' }); + } + + const credentials = GoogleCredentialsLoader.ProjectCredentials; + const auth = new google.auth.OAuth2( + credentials.client_id, + credentials.client_secret, + credentials.redirect_uris[0] + ); + + auth.setCredentials({ access_token: accessToken }); + + const tasks = google.tasks({ version: 'v1', auth }); + + const result = await tasks.tasks.insert({ + tasklist: '@default', + requestBody: { + title, + notes, + due, + }, + }); + + res.status(200).json(result.data); + } catch (err) { + console.error('Error creating Google Task:', err); + res.status(500).json({ error: 'Failed to create task' }); + } +}); + +export default router; |