]> gerrit.midnightthoughts Code Review - neoboard-miro-converter.git/commitdiff
Improve the output and allow logout
authorMTRNord <mtrnord1@gmail.com>
Sat, 11 Jan 2025 17:39:19 +0000 (18:39 +0100)
committerMTRNord <mtrnord1@gmail.com>
Sat, 11 Jan 2025 17:39:19 +0000 (18:39 +0100)
src/app/api/redirect/route.ts
src/app/importActions.ts
src/app/logoutAction.ts [new file with mode: 0644]
src/app/logoutComponent.tsx [new file with mode: 0644]
src/app/page.tsx
src/utils/initMiroAPI.ts

index 3523d386183620dda1e2648a3b1cc013bee3ff0e..b4aeb0b6f5d2a379fd91509c1177874c7a998a0b 100644 (file)
@@ -1,10 +1,12 @@
-import type {NextRequest} from 'next/server';
-import {redirect} from 'next/navigation';
+import type { NextRequest } from 'next/server';
+import { redirect } from 'next/navigation';
 import initMiroAPI from '../../../utils/initMiroAPI';
 
 // handle redirect with code and exchange it for the access token
 export async function GET(request: NextRequest) {
-  const {miro, userId} = initMiroAPI();
+  const { miro, userId } = initMiroAPI();
+
+  const awaitedUserId = await userId();
 
   // Make sure the code is in query parameters
   const code = request.nextUrl.searchParams.get('code');
@@ -14,7 +16,7 @@ export async function GET(request: NextRequest) {
   }
 
   try {
-    await miro.exchangeCodeForAccessToken(userId, code);
+    await miro.exchangeCodeForAccessToken(awaitedUserId, code);
   } catch (error) {
     redirect('/?error');
   }
index a959a61b1986bbcad0aeb414985769b50eea357b..bb4d2311bc6d8a60e16ba802a1143bc75f18f22c 100644 (file)
@@ -1,6 +1,6 @@
 'use server';
 
-import { AppCardItem, CardItem, DocumentItem, EmbedItem, FrameItem, ImageItem, Item, ShapeItem, StickyNoteItem, TextItem } from '@mirohq/miro-api';
+import { AppCardItem, Board, CardItem, DocumentItem, EmbedItem, FrameItem, ImageItem, Item, ShapeItem, StickyNoteItem, TextItem } from '@mirohq/miro-api';
 import initMiroAPI from '../utils/initMiroAPI';
 import { Path, Shape, Slide, Whiteboard, Image, neoboardWhiteboardWidth, neoboardWhiteboardHeight } from './neoboardTypes';
 import { stripHtml } from 'string-strip-html';
@@ -81,7 +81,7 @@ export async function importBoard(prevState: FormState, formData: FormData): Pro
                 if (item.parent.id === frameId) {
                     switch (item.type) {
                         case 'shape':
-                            const shape = convertShape(item as ShapeItem);
+                            const shape = await convertShape(item as ShapeItem, board);
                             if (shape) {
                                 slide.elements.push(shape);
                             }
@@ -196,7 +196,7 @@ function transformBoardIntoNeoboardCoordinates(board: Whiteboard): Whiteboard {
     return transformedBoard;
 }
 
-function convertShape(item: ShapeItem): Shape | undefined {
+async function convertShape(item: ShapeItem, board: Board): Promise<Shape | undefined> {
     let shapeType = item.data?.shape;
     let borderRadius = 0;
     if (shapeType !== 'rectangle' && shapeType !== 'circle' && shapeType !== 'ellipse' && shapeType !== 'triangle' && shapeType !== 'round_rectangle') {
@@ -205,9 +205,12 @@ function convertShape(item: ShapeItem): Shape | undefined {
     }
     if (shapeType === 'round_rectangle') {
         shapeType = 'rectangle';
-        borderRadius = 10;
+        borderRadius = 25;
     }
 
+    // Get shape item from Miro API
+    item = await board.getItem(item.id) as ShapeItem;
+
     const opacity = item.style?.fillOpacity ?? (item.style?.fillColor ? "1.0" : "0.0");
     const borderColorOpacity = item.style?.borderOpacity ?? "1.0";
 
@@ -325,7 +328,7 @@ function convertStickyNote(item: StickyNoteItem): Shape {
         fillColor: item.style?.fillColor ?? "#ffffff",
         strokeColor: 'transparent',
         strokeWidth: 0,
-        borderRadius: 10,
+        borderRadius: 25,
         text: stripHtml(item.data?.content ?? "").result,
         textAlignment: (item.style?.textAlign ?? "left") as "left" | "center" | "right",
         textColor: 'black',
diff --git a/src/app/logoutAction.ts b/src/app/logoutAction.ts
new file mode 100644 (file)
index 0000000..a69ec7b
--- /dev/null
@@ -0,0 +1,9 @@
+"use server";
+
+import { redirect } from "next/navigation";
+import { logoutMiroAPI } from "../utils/initMiroAPI";
+
+export default async function logout() {
+    await logoutMiroAPI();
+    redirect("/");
+}
\ No newline at end of file
diff --git a/src/app/logoutComponent.tsx b/src/app/logoutComponent.tsx
new file mode 100644 (file)
index 0000000..25eb1da
--- /dev/null
@@ -0,0 +1,16 @@
+"use server";
+
+import logout from "./logoutAction";
+
+export default async function Logout() {
+    return (
+        <div>
+            <h3>Logout</h3>
+            <form action={logout}>
+                <button className="button button-danger" type="submit">
+                    Logout
+                </button>
+            </form>
+        </div>
+    )
+}
\ No newline at end of file
index f9b146a0434fd8943d7023126832a7b2a531947c..216719436a1d295d6858b551a6c4716895bf3145 100644 (file)
@@ -5,6 +5,7 @@ import { Board } from '@mirohq/miro-api';
 import initMiroAPI from '../utils/initMiroAPI';
 import '../assets/style.scss';
 import SelectionFormComponent from './selectionFormComponent';
+import Logout from './logoutComponent';
 
 const getBoards = async () => {
   const { miro, userId } = initMiroAPI();
@@ -41,7 +42,7 @@ export default async function Page() {
     return (
       <div>
         <h3>Login</h3>
-        <a className="button button-primary" href={authUrl} target="_blank">
+        <a className="button button-primary" href={authUrl}>
           Login
         </a>
       </div>
@@ -52,5 +53,11 @@ export default async function Page() {
     return <div>Loading...</div>;
   }
 
-  return (<><SelectionFormComponent boards={safeBoards} /></>);
+  return (
+    <>
+      <Logout />
+      <hr className="cs1 ce12" />
+      <SelectionFormComponent boards={safeBoards} />
+    </>
+  );
 }
index f39be1dd76e992421344735a52cb8da8cbb0e103..7acce7cfc99a496be26f8b550642230391c89f39 100644 (file)
@@ -4,6 +4,18 @@ import { State } from '@mirohq/miro-api/dist/storage';
 
 const tokensCookie = 'miro_tokens';
 
+export async function logoutMiroAPI() {
+  const { miro, userId } = initMiroAPI();
+  const userIdAwaited = await userId();
+
+  if (userIdAwaited) {
+    await miro.as(userIdAwaited).revokeToken();
+  }
+
+  const cookieInstance = await cookies();
+  cookieInstance.delete('miro_tokens');
+}
+
 export default function initMiroAPI() {
   const cookieInstance = cookies();