diff --git a/apps/backend/src/api/routes/billing.controller.ts b/apps/backend/src/api/routes/billing.controller.ts index 988eabc1..134c9de5 100644 --- a/apps/backend/src/api/routes/billing.controller.ts +++ b/apps/backend/src/api/routes/billing.controller.ts @@ -6,13 +6,15 @@ import { Organization, User } from '@prisma/client'; import { BillingSubscribeDto } from '@gitroom/nestjs-libraries/dtos/billing/billing.subscribe.dto'; import { ApiTags } from '@nestjs/swagger'; import { GetUserFromRequest } from '@gitroom/nestjs-libraries/user/user.from.request'; +import { NotificationService } from '@gitroom/nestjs-libraries/database/prisma/notifications/notification.service'; @ApiTags('Billing') @Controller('/billing') export class BillingController { constructor( private _subscriptionService: SubscriptionService, - private _stripeService: StripeService + private _stripeService: StripeService, + private _notificationService: NotificationService ) {} @Get('/check/:id') @@ -53,7 +55,16 @@ export class BillingController { } @Post('/cancel') - cancel(@GetOrgFromRequest() org: Organization) { + async cancel( + @GetOrgFromRequest() org: Organization, + @Body() body: { feedback: string } + ) { + await this._notificationService.sendEmail( + process.env.EMAIL_FROM_ADDRESS, + 'Subscription Cancelled', + `Organization ${org.name} has cancelled their subscription because: ${body.feedback}` + ); + return this._stripeService.setToCancel(org.id); } @@ -83,6 +94,10 @@ export class BillingController { throw new Error('Unauthorized'); } - await this._subscriptionService.addSubscription(org.id, user.id, body.subscription); + await this._subscriptionService.addSubscription( + org.id, + user.id, + body.subscription + ); } } diff --git a/apps/frontend/src/components/billing/main.billing.component.tsx b/apps/frontend/src/components/billing/main.billing.component.tsx index dc55b7fd..fc2f88d2 100644 --- a/apps/frontend/src/components/billing/main.billing.component.tsx +++ b/apps/frontend/src/components/billing/main.billing.component.tsx @@ -1,7 +1,7 @@ 'use client'; import { Slider } from '@gitroom/react/form/slider'; -import { FC, useCallback, useEffect, useMemo, useState } from 'react'; +import React, { FC, useCallback, useEffect, useMemo, useState } from 'react'; import { Button } from '@gitroom/react/form/button'; import { sortBy } from 'lodash'; import { Track } from '@gitroom/react/form/track'; @@ -20,6 +20,10 @@ import { useUser } from '@gitroom/frontend/components/layout/user.context'; import interClass from '@gitroom/react/helpers/inter.font'; import { useRouter } from 'next/navigation'; import { useVariables } from '@gitroom/react/helpers/variable.context'; +import { useModals } from '@mantine/modals'; +import { AddProviderComponent } from '@gitroom/frontend/components/launches/add.provider.component'; +import { TopTitle } from '@gitroom/frontend/components/launches/helpers/top.title.component'; +import { Textarea } from '@gitroom/react/form/textarea'; export interface Tiers { month: Array<{ @@ -149,15 +153,71 @@ export const Features: FC<{ ); }; +const Info: FC<{ proceed: (feedback: string) => void }> = (props) => { + const [feedback, setFeedback] = useState(''); + const modal = useModals(); + + const cancel = useCallback(() => { + props.proceed(feedback); + modal.closeAll(); + }, [modal, feedback]); + + return ( +