From 46d3943596997516269ec25b1967ba5b5bc1358b Mon Sep 17 00:00:00 2001 From: Nevo David Date: Wed, 12 Feb 2025 21:36:41 +0700 Subject: [PATCH] feat: signatures --- apps/backend/src/api/api.module.ts | 6 +- .../src/api/routes/signature.controller.ts | 39 +++ .../src/components/launches/calendar.tsx | 9 +- .../src/components/launches/editor.tsx | 2 + .../components/layout/settings.component.tsx | 261 ++++++++++-------- .../settings/signatures.component.tsx | 208 ++++++++++++++ apps/frontend/src/components/signature.tsx | 79 ++++++ .../src/database/prisma/database.module.ts | 4 + .../database/prisma/posts/posts.service.ts | 26 +- .../src/database/prisma/schema.prisma | 16 ++ .../prisma/signatures/signature.repository.ts | 48 ++++ .../prisma/signatures/signature.service.ts | 20 ++ .../src/dtos/signature/signature.dto.ts | 11 + 13 files changed, 601 insertions(+), 128 deletions(-) create mode 100644 apps/backend/src/api/routes/signature.controller.ts create mode 100644 apps/frontend/src/components/settings/signatures.component.tsx create mode 100644 apps/frontend/src/components/signature.tsx create mode 100644 libraries/nestjs-libraries/src/database/prisma/signatures/signature.repository.ts create mode 100644 libraries/nestjs-libraries/src/database/prisma/signatures/signature.service.ts create mode 100644 libraries/nestjs-libraries/src/dtos/signature/signature.dto.ts diff --git a/apps/backend/src/api/api.module.ts b/apps/backend/src/api/api.module.ts index 4fb94fbf..e96f13d3 100644 --- a/apps/backend/src/api/api.module.ts +++ b/apps/backend/src/api/api.module.ts @@ -29,6 +29,7 @@ import { TrackService } from '@gitroom/nestjs-libraries/track/track.service'; import { ShortLinkService } from '@gitroom/nestjs-libraries/short-linking/short.link.service'; import { Nowpayments } from '@gitroom/nestjs-libraries/crypto/nowpayments'; import { WebhookController } from '@gitroom/backend/api/routes/webhooks.controller'; +import { SignatureController } from '@gitroom/backend/api/routes/signature.controller'; const authenticatedController = [ UsersController, @@ -44,11 +45,10 @@ const authenticatedController = [ CopilotController, AgenciesController, WebhookController, + SignatureController, ]; @Module({ - imports: [ - UploadModule, - ], + imports: [UploadModule], controllers: [ RootController, StripeController, diff --git a/apps/backend/src/api/routes/signature.controller.ts b/apps/backend/src/api/routes/signature.controller.ts new file mode 100644 index 00000000..2162443b --- /dev/null +++ b/apps/backend/src/api/routes/signature.controller.ts @@ -0,0 +1,39 @@ +import { Body, Controller, Get, Param, Post, Put } from '@nestjs/common'; +import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request'; +import { Organization } from '@prisma/client'; +import { ApiTags } from '@nestjs/swagger'; +import { SignatureService } from '@gitroom/nestjs-libraries/database/prisma/signatures/signature.service'; +import { SignatureDto } from '@gitroom/nestjs-libraries/dtos/signature/signature.dto'; + +@ApiTags('Signatures') +@Controller('/signatures') +export class SignatureController { + constructor(private _signatureService: SignatureService) {} + + @Get('/') + async getSignatures(@GetOrgFromRequest() org: Organization) { + return this._signatureService.getSignaturesByOrgId(org.id); + } + + @Get('/default') + async getDefaultSignature(@GetOrgFromRequest() org: Organization) { + return (await this._signatureService.getDefaultSignature(org.id)) || {}; + } + + @Post('/') + async createSignature( + @GetOrgFromRequest() org: Organization, + @Body() body: SignatureDto + ) { + return this._signatureService.createOrUpdateSignature(org.id, body); + } + + @Put('/:id') + async updateSignature( + @Param('id') id: string, + @GetOrgFromRequest() org: Organization, + @Body() body: SignatureDto + ) { + return this._signatureService.createOrUpdateSignature(org.id, body, id); + } +} diff --git a/apps/frontend/src/components/launches/calendar.tsx b/apps/frontend/src/components/launches/calendar.tsx index 9f076e80..a51caf74 100644 --- a/apps/frontend/src/components/launches/calendar.tsx +++ b/apps/frontend/src/components/launches/calendar.tsx @@ -490,7 +490,9 @@ export const CalendarColumn: FC<{ [integrations] ); - const addModal = useCallback(() => { + const addModal = useCallback(async () => { + const signature = await (await fetch('/signatures/default')).json(); + modal.openModal({ closeOnClickOutside: false, closeOnEscape: false, @@ -503,6 +505,11 @@ export const CalendarColumn: FC<{ allIntegrations={integrations.map((p) => ({ ...p }))} integrations={integrations.slice(0).map((p) => ({ ...p }))} mutate={reloadCalendarView} + {...(signature?.id + ? { + onlyValues: [{ content: '\n' + signature.content }], + } + : {})} date={ randomHour ? getDate.hour(Math.floor(Math.random() * 24)) : getDate } diff --git a/apps/frontend/src/components/launches/editor.tsx b/apps/frontend/src/components/launches/editor.tsx index 224ca0e3..11cf4918 100644 --- a/apps/frontend/src/components/launches/editor.tsx +++ b/apps/frontend/src/components/launches/editor.tsx @@ -11,6 +11,7 @@ import EmojiPicker from 'emoji-picker-react'; import { Theme } from 'emoji-picker-react'; import { BoldText } from '@gitroom/frontend/components/launches/bold.text'; import { UText } from '@gitroom/frontend/components/launches/u.text'; +import { SignatureBox } from '@gitroom/frontend/components/signature'; export const Editor = forwardRef< RefMDEditor, @@ -61,6 +62,7 @@ export const Editor = forwardRef< return ( <>
+ }> = (props) => { const { isGeneral } = useVariables(); @@ -76,6 +78,22 @@ export const SettingsPopup: FC<{ getRef?: Ref }> = (props) => { close(); }, []); + const defaultValueForTabs = useMemo(() => { + if (user?.tier?.team_members && isGeneral) { + return 'teams'; + } + + if (user?.tier?.webhooks) { + return 'webhooks'; + } + + if (user?.tier?.public_api && isGeneral) { + return 'api'; + } + + return 'teams'; + }, []); + useEffect(() => { loadProfile(); }, []); @@ -92,118 +110,139 @@ export const SettingsPopup: FC<{ getRef?: Ref }> = (props) => { !getRef && 'rounded-[4px]' )} > - {/*{!getRef && (*/} - {/* */} - {/* */} - {/* */} - {/* */} - {/* */} - {/*)}*/} - {/*{!getRef && (*/} - {/*
Profile Settings
*/} - {/*)}*/} - {/*
*/} - {/*
Profile
*/} - {/*
*/} - {/* Add profile information*/} - {/*
*/} - {/*
*/} - {/*
*/} - {/*
*/} - {/*
*/} - {/* */} - {/*
*/} - {/*
*/} - {/*
*/} - {/* {!!picture?.path && (*/} - {/* */} - {/* )}*/} - {/*
*/} - {/*
*/} - {/*
Profile Picture
*/} - {/*
*/} - {/* */} - {/*
*/} - {/* */} - {/* */} - {/* */} - {/*
*/} - {/*
*/} - {/* Upload image*/} - {/*
*/} - {/* */} - {/* */} - {/*
*/} - {/* */} - {/* */} - {/* */} - {/*
*/} - {/*
*/} - {/* Remove*/} - {/*
*/} - {/* */} - {/*
*/} - {/*
*/} - {/*
*/} - {/*
*/} - {/*
*/} - {/*