From 571ddfba856ab4907a44ab258cffefa5bfb5b774 Mon Sep 17 00:00:00 2001 From: PxlLoewe <72106766+PxlLoewe@users.noreply.github.com> Date: Tue, 27 May 2025 17:34:44 -0700 Subject: [PATCH] Fixed docker deploments, moved files to _folders in dispatch app --- .dockerignore | 3 +- .env.prod | 98 +++++++++++------ README.md | 102 +----------------- apps/dispatch-server/index.ts | 4 +- apps/dispatch-server/modules/redis.ts | 4 +- apps/dispatch-server/package.json | 5 +- apps/dispatch/.dockerignore | 3 +- apps/dispatch/.env.example | 8 +- apps/dispatch/Dockerfile | 16 +++ .../app/(auth)/login/_components/Login.tsx | 12 +-- apps/dispatch/app/_components/Audio.tsx | 2 +- .../app/_components/MicVolumeIndication.tsx | 2 +- apps/dispatch/app/_components/Select.tsx | 37 ++----- apps/dispatch/app/_components/Settings.tsx | 2 +- apps/dispatch/app/_components/SmartPopup.tsx | 19 ++-- .../customToasts/BaseNotification.tsx | 2 +- apps/dispatch/app/_components/left/Chat.tsx | 26 ++--- apps/dispatch/app/_components/left/Report.tsx | 19 ++-- .../app/_components/map/AircraftMarker.tsx | 58 +++------- .../app/_components/map/ContextMenu.tsx | 2 +- .../app/_components/map/MissionMarkers.tsx | 8 +- .../app/_components/map/SearchElements.tsx | 2 +- .../map/_components/AircraftMarkerTabs.tsx | 34 ++---- .../map/_components/MarkerCluster.tsx | 10 +- .../map/_components/MissionMarkerTabs.tsx | 12 +-- .../app/{helpers => _helpers}/axios.ts | 0 apps/dispatch/app/{helpers => _helpers}/cn.ts | 0 .../hpgStateToFmsStatus.ts | 0 .../hpgValidationRequired.ts | 0 .../liveKitEventHandler.ts | 0 .../app/{helpers => _helpers}/radioAudio.ts | 0 .../selectRandomHPGMission.ts | 0 .../simulatorConnected.ts | 0 .../app/{querys => _querys}/aircrafts.ts | 12 +-- .../app/{querys => _querys}/connected-user.ts | 0 .../app/{querys => _querys}/keywords.ts | 0 .../app/{querys => _querys}/missions.ts | 2 +- apps/dispatch/app/{querys => _querys}/osm.ts | 0 .../app/{querys => _querys}/report.ts | 12 +-- .../app/{querys => _querys}/stations.ts | 0 apps/dispatch/app/{querys => _querys}/user.ts | 0 apps/dispatch/app/_store/audioStore.ts | 4 +- .../app/api/auth/[...nextauth]/auth.ts | 11 +- .../_components/pannel/MissionForm.tsx | 12 +-- .../dispatch/_components/pannel/Pannel.tsx | 11 +- apps/dispatch/app/dispatch/page.tsx | 2 +- apps/dispatch/app/dispatch/socket.ts | 4 +- .../app/pilot/_components/mrt/useButtons.ts | 9 +- .../navbar/_components/Connection.tsx | 2 +- apps/dispatch/app/pilot/socket.ts | 1 - apps/hub/.env.example | 4 +- apps/hub/Dockerfile | 4 +- .../app/(auth)/login/_components/Login.tsx | 15 +-- apps/hub/app/_components/Nav.tsx | 13 +-- apps/hub/app/api/auth/[...nextauth]/auth.ts | 6 +- apps/hub/app/api/auth/accessToken/route.ts | 2 +- apps/hub/app/api/user/route.ts | 10 +- apps/hub/app/layout.tsx | 10 +- docker-compose.prod.yml | 17 ++- turbo.json | 4 +- 60 files changed, 251 insertions(+), 406 deletions(-) rename apps/dispatch/app/{helpers => _helpers}/axios.ts (100%) rename apps/dispatch/app/{helpers => _helpers}/cn.ts (100%) rename apps/dispatch/app/{helpers => _helpers}/hpgStateToFmsStatus.ts (100%) rename apps/dispatch/app/{helpers => _helpers}/hpgValidationRequired.ts (100%) rename apps/dispatch/app/{helpers => _helpers}/liveKitEventHandler.ts (100%) rename apps/dispatch/app/{helpers => _helpers}/radioAudio.ts (100%) rename apps/dispatch/app/{helpers => _helpers}/selectRandomHPGMission.ts (100%) rename apps/dispatch/app/{helpers => _helpers}/simulatorConnected.ts (100%) rename apps/dispatch/app/{querys => _querys}/aircrafts.ts (58%) rename apps/dispatch/app/{querys => _querys}/connected-user.ts (100%) rename apps/dispatch/app/{querys => _querys}/keywords.ts (100%) rename apps/dispatch/app/{querys => _querys}/missions.ts (97%) rename apps/dispatch/app/{querys => _querys}/osm.ts (100%) rename apps/dispatch/app/{querys => _querys}/report.ts (52%) rename apps/dispatch/app/{querys => _querys}/stations.ts (100%) rename apps/dispatch/app/{querys => _querys}/user.ts (100%) diff --git a/.dockerignore b/.dockerignore index e6a5744f..004fb3ff 100644 --- a/.dockerignore +++ b/.dockerignore @@ -9,4 +9,5 @@ Dockerfile .dockerignore .eslint.config.msj .README.md -.env.example \ No newline at end of file +.env.example +.env \ No newline at end of file diff --git a/.env.prod b/.env.prod index 491dbeaa..38414e75 100644 --- a/.env.prod +++ b/.env.prod @@ -1,37 +1,73 @@ -# Allgemein / NextAuth -NEXTAUTH_URL=http://localhost:3000 -NEXTAUTH_COOKIE_PREFIX=HUB -NEXTAUTH_SECRET=var -NEXTAUTH_HUB_SECRET=var-hub-secret +# ─────────────────────────────────────────────── +# 🔐 Authentifizierung & Cookies +# ─────────────────────────────────────────────── +AUTH_DISPATCH_SECRET=dispatch +AUTH_HUB_SECRET=var -# Datenbank +AUTH_DISPATCH_COOKIE_PREFIX=DISPATCH +AUTH_HUB_COOKIE_PREFIX=HUB + +AUTH_DISPATCH_URL=http://localhost:3001 +AUTH_HUB_URL=http://localhost:3000 +NEXT_PUBLIC_DISPATCH_SERVICE_ID=1 + + +# ─────────────────────────────────────────────── +# 🌐 Öffentliche URLs +# ─────────────────────────────────────────────── +NEXT_PUBLIC_HUB_URL=http://localhost:3000 +NEXT_PUBLIC_HUB_SERVER_URL=http://localhost:3003 +NEXT_PUBLIC_DISPATCH_URL=http://localhost:3001 +NEXT_PUBLIC_DISPATCH_SERVER_URL=http://localhost:3002 + +# ─────────────────────────────────────────────── +# 🗄️ Datenbank +# ─────────────────────────────────────────────── DATABASE_URL=postgresql://persistant-data:persistant-data-pw@postgres:5432/var -# Discord +# ─────────────────────────────────────────────── +# 📡 LiveKit Konfiguration +# ─────────────────────────────────────────────── +NEXT_PUBLIC_LIVEKIT_URL=ws://localhost:7880 +LIVEKIT_API_KEY=APIAnsGdtdYp2Ho +LIVEKIT_API_SECRET=tdPjVsYUx8ddC7K9NvdmVAeLRF9GeADD6Fedm1x63fWC + +# ─────────────────────────────────────────────── +# 🚦 Dispatch Server (Backend) +# ─────────────────────────────────────────────── +DISPATCH_SERVER_PORT=3000 +DISPATCH_APP_TOKEN=dispatch + +REDIS_HOST=redis +REDIS_PORT=6379 + +# ─────────────────────────────────────────────── +# 🧠 HUB Server (Backend) +# ─────────────────────────────────────────────── +HUB_SERVER_PORT=3000 +HUB_URL= + +# ─────────────────────────────────────────────── +# 📚 Moodle +# ─────────────────────────────────────────────── +MOODLE_URL=http://localhost:8081 +MOODLE_API_TOKEN=ac346f0324647b68488d13fd52a9bbe8 +MOODLE_USER_PASSWORD=var-api-user-P1 +NEXT_PUBLIC_MOODLE_URL=http://localhost:8081 + +# ─────────────────────────────────────────────── +# 📧 E-Mail Einstellungen (nur HUB Server) +# ─────────────────────────────────────────────── +MAIL_SERVER=asmtp.mail.hostpoint.ch +MAIL_PORT=465 +MAIL_USER=noreply@virtualairrescue.com +MAIL_PASSWORD=b7316PB8aDPCC%-& + +# ─────────────────────────────────────────────── +# 🕹️ Discord OAuth (optional) +# ─────────────────────────────────────────────── DISCORD_OAUTH_CLIENT_ID= DISCORD_OAUTH_SECRET= DISCORD_BOT_TOKEN= -NEXT_PUBLIC_DISCORD_URL= -DISCORD_REDIRECT= - -# Moodle -MOODLE_PW=var-api-user-P1 -MOODLE_TOKEN=ac346f0324647b68488d13fd52a9bbe8 -NEXT_PUBLIC_MOODLE_URL=http://localhost:8081 - -# Hub Server -NEXT_PUBLIC_HUB_SERVER_URL=http://localhost:3003 - -# Dispatch Server -NEXT_PUBLIC_DISPATCH_SERVER_URL=http://localhost:3001 - -# Livekit -NEXT_PUBLIC_LIVEKIT_URL=http://localhost:7880 -LIVEKIT_API_KEY= -LIVEKIT_API_SECRET= - -# HUB Server -HUB_API_PORT=3000 - -# Redis (Beispiel) -REDIS_URL=redis://localhost:6379 \ No newline at end of file +DISCORD_REDIRECT_URL= +NEXT_PUBLIC_DISCORD_URL= \ No newline at end of file diff --git a/README.md b/README.md index 47f603fb..ff540a6f 100644 --- a/README.md +++ b/README.md @@ -1,103 +1,9 @@ -# Turborepo starter +# Turborepo Monorepo für LST V2 -This is an official starter Turborepo. +## Docker Dev -## Using this example - -Run the following command: +Um lokal Docker-Images zu bauen, gib die `.env`-Datei mit folgendem Befehl an `docker compose` weiter: ```sh -npx create-turbo@latest +docker compose --env-file .env.prod -f 'docker-compose.prod.yml' up -d ``` - -## What's inside? - -This Turborepo includes the following packages/apps: - -### Apps and Packages - -- `dispatch`: a dispatching platform for web based unit/mission dispatching -- `docs`: a [Next.js](https://nextjs.org/) app -- `@repo/ui`: a stub React component library shared by both `web` and `docs` applications -- `@repo/eslint-config`: `eslint` configurations (includes `eslint-config-next` and `eslint-config-prettier`) -- `@repo/typescript-config`: `tsconfig.json`s used throughout the monorepo - -Each package/app is 100% [TypeScript](https://www.typescriptlang.org/). - -### Utilities - -This Turborepo has some additional tools already setup for you: - -- [TypeScript](https://www.typescriptlang.org/) for static type checking -- [ESLint](https://eslint.org/) for code linting -- [Prettier](https://prettier.io) for code formatting - -### Build - -To build all apps and packages, run the following command: - -``` -cd my-turborepo -pnpm build -``` - -### Develop - -To develop all apps and packages, run the following command: - -``` -cd my-turborepo -pnpm dev -``` - -### Remote Caching - -> [!TIP] -> Vercel Remote Cache is free for all plans. Get started today at [vercel.com](https://vercel.com/signup?/signup?utm_source=remote-cache-sdk&utm_campaign=free_remote_cache). - -Turborepo can use a technique known as [Remote Caching](https://turbo.build/repo/docs/core-concepts/remote-caching) to share cache artifacts across machines, enabling you to share build caches with your team and CI/CD pipelines. - -By default, Turborepo will cache locally. To enable Remote Caching you will need an account with Vercel. If you don't have an account you can [create one](https://vercel.com/signup?utm_source=turborepo-examples), then enter the following commands: - -``` -cd my-turborepo -npx turbo login -``` - -This will authenticate the Turborepo CLI with your [Vercel account](https://vercel.com/docs/concepts/personal-accounts/overview). - -Next, you can link your Turborepo to your Remote Cache by running the following command from the root of your Turborepo: - -``` -npx turbo link -``` - -## Useful Links - -Learn more about the power of Turborepo: - -- [Tasks](https://turbo.build/repo/docs/core-concepts/monorepos/running-tasks) -- [Caching](https://turbo.build/repo/docs/core-concepts/caching) -- [Remote Caching](https://turbo.build/repo/docs/core-concepts/remote-caching) -- [Filtering](https://turbo.build/repo/docs/core-concepts/monorepos/filtering) -- [Configuration Options](https://turbo.build/repo/docs/reference/configuration) -- [CLI Usage](https://turbo.build/repo/docs/reference/command-line-reference) - -## Execution policy - -MachinePolicy Undefined -UserPolicy Undefined -Process Undefined -CurrentUser RemoteSigned -LocalMachine RemoteSigned - -## Moodle: - -1. Im docker volume gehe in lib -> Classes -> OAuth2 -> Endpoint.php -2. überspringe die https enforcement rule am Ende der Datei (true in if abfrage) -3. Moodle Admin -> General -> HTTP Security -> Curl einschränkungen löschen -4. http://localhost:8081/admin/category.php?category=authsettings -> Guest login button -> Hide -5. http://localhost:8081/admin/settings.php?section=sitepolicies -> emailchangeconfirmation -> False -6. Beim anlegen des Auth-Services Require Email verification deaktivieren -7. Beim erstellen der Role für API user: permission moodle/site:viewuseridentity geben -8. API user zu moodle kursen hinzufügen, um andere Nutzer hinzuzufügen diff --git a/apps/dispatch-server/index.ts b/apps/dispatch-server/index.ts index 09581c3e..bbb08eba 100644 --- a/apps/dispatch-server/index.ts +++ b/apps/dispatch-server/index.ts @@ -47,6 +47,6 @@ app.use(cookieParser()); app.use(authMiddleware as any); app.use(router); -server.listen(process.env.PORT, () => { - console.log(`Server running on port ${process.env.PORT}`); +server.listen(process.env.DISPATCH_SERVER_PORT, () => { + console.log(`Server running on port ${process.env.DISPATCH_SERVER_PORT}`); }); diff --git a/apps/dispatch-server/modules/redis.ts b/apps/dispatch-server/modules/redis.ts index e31cab05..ff7d7415 100644 --- a/apps/dispatch-server/modules/redis.ts +++ b/apps/dispatch-server/modules/redis.ts @@ -1,6 +1,8 @@ import { createClient, RedisClientType } from "redis"; -export const pubClient: RedisClientType = createClient(); +export const pubClient: RedisClientType = createClient({ + url: `redis://${process.env.REDIS_HOST}:${process.env.REDIS_PORT}`, +}); export const subClient: RedisClientType = pubClient.duplicate(); Promise.all([pubClient.connect(), subClient.connect()]).then(() => { diff --git a/apps/dispatch-server/package.json b/apps/dispatch-server/package.json index 24189b39..6c0edf9c 100644 --- a/apps/dispatch-server/package.json +++ b/apps/dispatch-server/package.json @@ -5,7 +5,7 @@ }, "scripts": { "dev": "nodemon --signal SIGINT", - "start": "node index.js", + "start": "tsx index.ts --transpile-only", "build": "tsc" }, "devDependencies": { @@ -34,6 +34,7 @@ "nodemailer": "^6.10.0", "react": "^19.0.0", "redis": "^4.7.0", - "socket.io": "^4.8.1" + "socket.io": "^4.8.1", + "tsx": "^4.19.4" } } diff --git a/apps/dispatch/.dockerignore b/apps/dispatch/.dockerignore index 3f569ce2..325bc2bd 100644 --- a/apps/dispatch/.dockerignore +++ b/apps/dispatch/.dockerignore @@ -3,4 +3,5 @@ Dockerfile .dockerignore .eslint.config.msj .README.md -.env.example \ No newline at end of file +.env.example +.env \ No newline at end of file diff --git a/apps/dispatch/.env.example b/apps/dispatch/.env.example index ae8f55ea..1ec06832 100644 --- a/apps/dispatch/.env.example +++ b/apps/dispatch/.env.example @@ -1,10 +1,10 @@ -NEXTAUTH_SECRET=dispatch -NEXTAUTH_COOKIE_PREFIX=DISPATCH +AUTH_DISPATCH_SECRET=dispatch +AUTH_DISPATCH_COOKIE_PREFIX=DISPATCH NEXT_PUBLIC_DISPATCH_SERVER_URL=http://localhost:3002 NEXTAUTH_URL=http://localhost:3001 NEXT_PUBLIC_HUB_URL=http://localhost:3000 -NEXT_PUBLIC_PUBLIC_URL=http://localhost:3001 -NEXT_PUBLIC_SERVICE_ID=1 +NEXT_PUBLIC_DISPATCH_URL=http://localhost:3001 +NEXT_PUBLIC_DISPATCH_SERVICE_ID=1 DATABASE_URL=postgresql://persistant-data:persistant-data-pw@localhost:5432/var NEXT_PUBLIC_LIVEKIT_URL=ws://localhost:7880 LIVEKIT_API_KEY=APIAnsGdtdYp2Ho diff --git a/apps/dispatch/Dockerfile b/apps/dispatch/Dockerfile index a6cc8923..52967528 100644 --- a/apps/dispatch/Dockerfile +++ b/apps/dispatch/Dockerfile @@ -1,5 +1,17 @@ FROM node:22-alpine AS base +ARG NEXT_PUBLIC_DISPATCH_URL +ARG NEXT_PUBLIC_DISPATCH_SERVER_URL +ARG NEXT_PUBLIC_HUB_URL +ARG NEXT_PUBLIC_DISPATCH_SERVICE_ID +ARG NEXT_PUBLIC_LIVEKIT_URL + +ENV NEXT_PUBLIC_DISPATCH_SERVER_URL=$NEXT_PUBLIC_DISPATCH_SERVER_URL +ENV NEXT_PUBLIC_DISPATCH_URL=$NEXT_PUBLIC_DISPATCH_URL +ENV NEXT_PUBLIC_HUB_URL=$NEXT_PUBLIC_HUB_URL +ENV NEXT_PUBLIC_DISPATCH_SERVICE_ID=$NEXT_PUBLIC_DISPATCH_SERVICE_ID +ENV NEXT_PUBLIC_LIVEKIT_URL=$NEXT_PUBLIC_LIVEKIT_URL + ENV PNPM_HOME="/usr/local/pnpm" ENV PATH="${PNPM_HOME}:${PATH}" RUN corepack enable && corepack prepare pnpm@latest --activate @@ -12,6 +24,10 @@ RUN apk add --no-cache libc6-compat WORKDIR /usr/app +RUN echo "NEXT_PUBLIC_HUB_URL is: $NEXT_PUBLIC_HUB_URL" +RUN echo "NEXT_PUBLIC_DISPATCH_SERVICE_ID is: $NEXT_PUBLIC_DISPATCH_SERVICE_ID" +RUN echo "NEXT_PUBLIC_DISPATCH_SERVER_URL is: $NEXT_PUBLIC_DISPATCH_SERVER_URL" + COPY . . RUN turbo prune dispatch --docker diff --git a/apps/dispatch/app/(auth)/login/_components/Login.tsx b/apps/dispatch/app/(auth)/login/_components/Login.tsx index 0e9be153..93440f59 100644 --- a/apps/dispatch/app/(auth)/login/_components/Login.tsx +++ b/apps/dispatch/app/(auth)/login/_components/Login.tsx @@ -49,16 +49,10 @@ export const Login = () => {
- diff --git a/apps/dispatch/app/_components/Audio.tsx b/apps/dispatch/app/_components/Audio.tsx index c765ed56..d16dfbbc 100644 --- a/apps/dispatch/app/_components/Audio.tsx +++ b/apps/dispatch/app/_components/Audio.tsx @@ -15,7 +15,7 @@ import { ZapOff, } from "lucide-react"; import { useAudioStore } from "_store/audioStore"; -import { cn } from "helpers/cn"; +import { cn } from "_helpers/cn"; import { ConnectionQuality } from "livekit-client"; import { ROOMS } from "_data/livekitRooms"; diff --git a/apps/dispatch/app/_components/MicVolumeIndication.tsx b/apps/dispatch/app/_components/MicVolumeIndication.tsx index c1dde18b..f8683f57 100644 --- a/apps/dispatch/app/_components/MicVolumeIndication.tsx +++ b/apps/dispatch/app/_components/MicVolumeIndication.tsx @@ -1,6 +1,6 @@ "use client"; -import { cn } from "helpers/cn"; +import { cn } from "_helpers/cn"; import { useEffect, useState } from "react"; type MicrophoneLevelProps = { diff --git a/apps/dispatch/app/_components/Select.tsx b/apps/dispatch/app/_components/Select.tsx index 25311197..d59fb594 100644 --- a/apps/dispatch/app/_components/Select.tsx +++ b/apps/dispatch/app/_components/Select.tsx @@ -1,20 +1,11 @@ "use client"; -import { - FieldValues, - Path, - RegisterOptions, - UseFormReturn, -} from "react-hook-form"; -import SelectTemplate, { - Props as SelectTemplateProps, - StylesConfig, -} from "react-select"; -import { cn } from "helpers/cn"; +import { FieldValues, Path, RegisterOptions, UseFormReturn } from "react-hook-form"; +import SelectTemplate, { Props as SelectTemplateProps, StylesConfig } from "react-select"; +import { cn } from "_helpers/cn"; import dynamic from "next/dynamic"; import { CSSProperties } from "react"; -interface SelectProps - extends Omit { +interface SelectProps extends Omit { label?: any; name: Path; form: UseFormReturn | any; @@ -69,9 +60,7 @@ const SelectCom = ({ }: SelectProps) => { return (
- - {label} - + {label} { if (Array.isArray(newValue)) { @@ -88,12 +77,8 @@ const SelectCom = ({ }} value={ (inputProps as any)?.isMulti - ? (inputProps as any).options?.filter((o: any) => - form.watch(name)?.includes(o.value), - ) - : (inputProps as any).options?.find( - (o: any) => o.value === form.watch(name), - ) + ? (inputProps as any).options?.filter((o: any) => form.watch(name)?.includes(o.value)) + : (inputProps as any).options?.find((o: any) => o.value === form.watch(name)) } styles={customStyles as any} className={cn("w-full placeholder:text-neutral-600", className)} @@ -101,17 +86,13 @@ const SelectCom = ({ {...inputProps} /> {form.formState.errors[name]?.message && ( -

- {form.formState.errors[name].message as string} -

+

{form.formState.errors[name].message as string}

)}
); }; -const SelectWrapper = (props: SelectProps) => ( - -); +const SelectWrapper = (props: SelectProps) => ; export const Select = dynamic(() => Promise.resolve(SelectWrapper), { ssr: false, diff --git a/apps/dispatch/app/_components/Settings.tsx b/apps/dispatch/app/_components/Settings.tsx index ece681de..ad9198be 100644 --- a/apps/dispatch/app/_components/Settings.tsx +++ b/apps/dispatch/app/_components/Settings.tsx @@ -4,7 +4,7 @@ import { GearIcon } from "@radix-ui/react-icons"; import { SettingsIcon, Volume2 } from "lucide-react"; import MicVolumeBar from "_components/MicVolumeIndication"; import { useMutation, useQuery } from "@tanstack/react-query"; -import { editUserAPI, getUserAPI } from "querys/user"; +import { editUserAPI, getUserAPI } from "_querys/user"; import { Prisma } from "@repo/db"; import { useSession } from "next-auth/react"; import { useAudioStore } from "_store/audioStore"; diff --git a/apps/dispatch/app/_components/SmartPopup.tsx b/apps/dispatch/app/_components/SmartPopup.tsx index 975211d7..a19a4a60 100644 --- a/apps/dispatch/app/_components/SmartPopup.tsx +++ b/apps/dispatch/app/_components/SmartPopup.tsx @@ -1,10 +1,5 @@ -import { cn } from "helpers/cn"; -import { - RefAttributes, - useCallback, - useEffect, - useImperativeHandle, -} from "react"; +import { cn } from "_helpers/cn"; +import { RefAttributes, useCallback, useEffect, useImperativeHandle } from "react"; import { createContext, Ref, useContext, useState } from "react"; import { Popup, PopupProps, useMap } from "react-leaflet"; import { Popup as LPopup } from "leaflet"; @@ -113,9 +108,9 @@ export const SmartPopup = ( const [showContent, setShowContent] = useState(false); const { smartPopupRef, id, className, wrapperClassName, options } = props; - const [anchor, setAnchor] = useState< - "topleft" | "topright" | "bottomleft" | "bottomright" - >("topleft"); + const [anchor, setAnchor] = useState<"topleft" | "topright" | "bottomleft" | "bottomright">( + "topleft", + ); const handleConflict = useCallback(() => { const newAnchor = calculateAnchor(id, "popup", options); @@ -160,9 +155,7 @@ export const SmartPopup = ( anchor.includes("top") && "-translate-y-1/2", )} /> - - {props.children} - + {props.children}
); diff --git a/apps/dispatch/app/_components/customToasts/BaseNotification.tsx b/apps/dispatch/app/_components/customToasts/BaseNotification.tsx index d51475fa..815d2979 100644 --- a/apps/dispatch/app/_components/customToasts/BaseNotification.tsx +++ b/apps/dispatch/app/_components/customToasts/BaseNotification.tsx @@ -1,4 +1,4 @@ -import { cn } from "helpers/cn"; +import { cn } from "_helpers/cn"; export const BaseNotification = ({ children, diff --git a/apps/dispatch/app/_components/left/Chat.tsx b/apps/dispatch/app/_components/left/Chat.tsx index 505561cb..579a5e17 100644 --- a/apps/dispatch/app/_components/left/Chat.tsx +++ b/apps/dispatch/app/_components/left/Chat.tsx @@ -3,10 +3,10 @@ import { ChatBubbleIcon, PaperPlaneIcon } from "@radix-ui/react-icons"; import { useLeftMenuStore } from "_store/leftMenuStore"; import { useSession } from "next-auth/react"; import { Fragment, useEffect, useState } from "react"; -import { cn } from "helpers/cn"; +import { cn } from "_helpers/cn"; import { asPublicUser } from "@repo/db"; import { useQuery } from "@tanstack/react-query"; -import { getConnectedUserAPI } from "querys/connected-user"; +import { getConnectedUserAPI } from "_querys/connected-user"; export const Chat = () => { const { @@ -88,8 +88,7 @@ export const Chat = () => { {[ ...(connectedUser?.filter( - (user, idx, arr) => - arr.findIndex((u) => u.userId === user.userId) === idx, + (user, idx, arr) => arr.findIndex((u) => u.userId === user.userId) === idx, ) || []), ].map((user) => (