feat: agencies

This commit is contained in:
Nevo David 2024-08-20 16:21:21 +07:00
parent da524bdc3e
commit c3f656f54e
8 changed files with 273 additions and 25 deletions

View File

@ -27,6 +27,7 @@ import { ExtractContentService } from '@gitroom/nestjs-libraries/openai/extract.
import { CodesService } from '@gitroom/nestjs-libraries/services/codes.service';
import { CopilotController } from '@gitroom/backend/api/routes/copilot.controller';
import { AgenciesController } from '@gitroom/backend/api/routes/agencies.controller';
import { PublicController } from '@gitroom/backend/api/routes/public.controller';
const authenticatedController = [
UsersController,
@ -62,7 +63,7 @@ const authenticatedController = [
]
: []),
],
controllers: [StripeController, AuthController, ...authenticatedController],
controllers: [StripeController, AuthController, PublicController, ...authenticatedController],
providers: [
AuthService,
StripeService,

View File

@ -1,4 +1,4 @@
import { Controller, Get, Post } from '@nestjs/common';
import { Body, Controller, Get, Post } from '@nestjs/common';
import { User } from '@prisma/client';
import { ApiTags } from '@nestjs/swagger';
import { AgenciesService } from '@gitroom/nestjs-libraries/database/prisma/agencies/agencies.service';
@ -10,12 +10,15 @@ import { CreateAgencyDto } from '@gitroom/nestjs-libraries/dtos/agencies/create.
export class AgenciesController {
constructor(private _agenciesService: AgenciesService) {}
@Get('/')
async generateImage(@GetUserFromRequest() user: User) {
async getAgencyByUser(@GetUserFromRequest() user: User) {
return this._agenciesService.getAgencyByUser(user);
}
@Post('/')
async createAgency(@GetUserFromRequest() user: User, body: CreateAgencyDto) {
async createAgency(
@GetUserFromRequest() user: User,
@Body() body: CreateAgencyDto
) {
return this._agenciesService.createAgency(user, body);
}
}

View File

@ -0,0 +1,30 @@
import { Controller, Get, Param } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { AgenciesService } from '@gitroom/nestjs-libraries/database/prisma/agencies/agencies.service';
@ApiTags('Public')
@Controller('/public')
export class PublicController {
constructor(private _agenciesService: AgenciesService) {}
@Get('/agencies-list')
async getAgencyByUser() {
return this._agenciesService.getAllAgencies();
}
@Get('/agencies-list-slug')
async getAgencySlug() {
return this._agenciesService.getAllAgenciesSlug();
}
@Get('/agencies-information/:agency')
async getAgencyInformation(
@Param('agency') agency: string,
) {
return this._agenciesService.getAgencyInformation(agency);
}
@Get('/agencies-list-count')
async getAgenciesCount() {
return this._agenciesService.getCount();
}
}

View File

@ -10,12 +10,64 @@ export class AgenciesRepository {
private _socialMediaAgenciesNiche: PrismaRepository<'socialMediaAgencyNiche'>
) {}
getAllAgencies() {
return this._socialMediaAgencies.model.socialMediaAgency.findMany({
where: {
deletedAt: null,
approved: true,
},
include: {
logo: true,
niches: true,
},
});
}
getCount() {
return this._socialMediaAgencies.model.socialMediaAgency.count({
where: {
deletedAt: null,
approved: true,
},
});
}
getAllAgenciesSlug() {
return this._socialMediaAgencies.model.socialMediaAgency.findMany({
where: {
deletedAt: null,
approved: true,
},
select: {
slug: true,
},
});
}
getAgencyInformation(agency: string) {
return this._socialMediaAgencies.model.socialMediaAgency.findFirst({
where: {
slug: agency,
deletedAt: null,
approved: true,
},
include: {
logo: true,
niches: true,
},
});
}
getAgencyByUser(user: User) {
return this._socialMediaAgencies.model.socialMediaAgency.findFirst({
where: {
userId: user.id,
deletedAt: null,
},
include: {
logo: true,
niches: true,
},
});
}
@ -32,17 +84,13 @@ export class AgenciesRepository {
facebook: body.facebook,
instagram: body.instagram,
twitter: body.twitter,
linkedIn: body.linkedin,
linkedIn: body.linkedIn,
youtube: body.youtube,
tiktok: body.tiktok,
logoId: body.logo,
logoId: body.logo.id,
shortDescription: body.shortDescription,
description: body.description,
niches: {
create: body.niche.map((n) => ({
niche: n,
})),
},
approved: false,
},
create: {
userId: user.id,
@ -51,12 +99,14 @@ export class AgenciesRepository {
facebook: body.facebook,
instagram: body.instagram,
twitter: body.twitter,
linkedIn: body.linkedin,
linkedIn: body.linkedIn,
youtube: body.youtube,
tiktok: body.tiktok,
logoId: body.logo,
logoId: body.logo.id,
shortDescription: body.shortDescription,
description: body.description,
slug: body.name.toLowerCase().replace(/ /g, '-'),
approved: false,
},
select: {
id: true,
@ -68,7 +118,7 @@ export class AgenciesRepository {
where: {
agencyId: insertAgency.id,
niche: {
notIn: body.niche,
notIn: body.niches,
},
},
}
@ -86,7 +136,7 @@ export class AgenciesRepository {
}
);
const addNewNiche = body.niche.filter(
const addNewNiche = body.niches.filter(
(n) => !currentNiche.some((c) => c.niche === n)
);

View File

@ -2,15 +2,164 @@ import { Injectable } from '@nestjs/common';
import { AgenciesRepository } from '@gitroom/nestjs-libraries/database/prisma/agencies/agencies.repository';
import { User } from '@prisma/client';
import { CreateAgencyDto } from '@gitroom/nestjs-libraries/dtos/agencies/create.agency.dto';
import { EmailService } from '@gitroom/nestjs-libraries/services/email.service';
@Injectable()
export class AgenciesService {
constructor(private _agenciesRepository: AgenciesRepository) {}
constructor(
private _agenciesRepository: AgenciesRepository,
private _emailService: EmailService
) {}
getAgencyByUser(user: User) {
return this._agenciesRepository.getAgencyByUser(user);
}
createAgency(user: User, body: CreateAgencyDto) {
return this._agenciesRepository.createAgency(user, body);
getCount() {
return this._agenciesRepository.getCount();
}
getAllAgencies() {
return this._agenciesRepository.getAllAgencies();
}
getAllAgenciesSlug() {
return this._agenciesRepository.getAllAgenciesSlug();
}
getAgencyInformation(agency: string) {
return this._agenciesRepository.getAgencyInformation(agency);
}
async createAgency(user: User, body: CreateAgencyDto) {
const agency = await this._agenciesRepository.createAgency(user, body);
await this._emailService.sendEmail(
'nevo@postiz.com',
'New agency created',
`
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Email Template</title>
</head>
<body style="font-family: Arial, sans-serif; margin: 0; padding: 0; background-color: #f4f4f4;">
<table align="center" cellpadding="0" cellspacing="0" style="max-width: 600px; width: 100%; background-color: #ffffff; margin-top: 20px; border: 1px solid #ddd;">
<tr>
<td style="padding: 0 20px 20px 20px; text-align: center;">
<!-- Website -->
<a href="${
body.website
}" style="text-decoration: none; color: #007bff;">${
body.website
}</a>
</td>
</tr>
<tr>
<td style="padding: 20px; text-align: center;">
<!-- Social Media Links -->
<p style="margin: 10px 0; font-size: 16px;">
Social Medias:
<a href="${
body.facebook
}" style="margin: 0 10px; text-decoration: none; color: #007bff;">${
body.facebook
}</a><br />
<a href="${
body.instagram
}" style="margin: 0 10px; text-decoration: none; color: #007bff;">${
body.instagram
}</a><br />
<a href="${
body.twitter
}" style="margin: 0 10px; text-decoration: none; color: #007bff;">${
body.twitter
}</a><br />
<a href="${
body.linkedIn
}" style="margin: 0 10px; text-decoration: none; color: #007bff;">${
body.linkedIn
}</a><br />
<a href="${
body.youtube
}" style="margin: 0 10px; text-decoration: none; color: #007bff;">${
body.youtube
}</a><br />
<a href="${
body.tiktok
}" style="margin: 0 10px; text-decoration: none; color: #007bff;">${
body.tiktok
}</a>
</p>
</td>
</tr>
<tr>
<td style="padding: 20px;">
<!-- Short Description -->
<h2 style="text-align: center; color: #333;">Logo</h2>
<p style="text-align: center; color: #555; font-size: 16px;">
<img src="${body.logo.path}" width="60" height="60" />
</p>
</td>
</tr>
<tr>
<td style="padding: 20px;">
<!-- Short Description -->
<h2 style="text-align: center; color: #333;">Name</h2>
<p style="text-align: center; color: #555; font-size: 16px;">${
body.name
}</p>
</td>
</tr>
<tr>
<td style="padding: 20px;">
<!-- Short Description -->
<h2 style="text-align: center; color: #333;">Short Description</h2>
<p style="text-align: center; color: #555; font-size: 16px;">${
body.shortDescription
}</p>
</td>
</tr>
<tr>
<td style="padding: 20px;">
<!-- Description -->
<h2 style="text-align: center; color: #333;">Description</h2>
<p style="text-align: center; color: #555; font-size: 16px;">${
body.description
}</p>
</td>
</tr>
<tr>
<td style="padding: 20px;">
<!-- Niches -->
<h2 style="text-align: center; color: #333;">Niches</h2>
<p style="text-align: center; color: #555; font-size: 16px;">${body.niches.join(
','
)}</p>
</td>
</tr>
<tr>
<td style="padding: 20px; text-align: center; background-color: #000;">
<a href="https://platform.postiz.com/agencies/${
agency.id
}/approve" style="margin: 0 10px; text-decoration: none; color: #007bff;">To approve click here</a><br /><br /><br />
<a href="https://platform.postiz.com/agencies/${
agency.id
}/decline" style="margin: 0 10px; text-decoration: none; color: #007bff;">To decline click here</a><br /><br /><br />
</td>
</tr>
<tr>
<td style="padding: 20px; text-align: center; background-color: #f4f4f4;">
<p style="color: #777; font-size: 14px;">&copy; 2024 Your Gitroom Limited All rights reserved.</p>
</td>
</tr>
</table>
</body>
</html>
`
);
return agency;
}
}

View File

@ -179,6 +179,7 @@ model SocialMediaAgency {
logoId String?
logo Media? @relation(fields: [logoId], references: [id])
website String?
slug String?
facebook String?
instagram String?

View File

@ -1,5 +1,13 @@
import { ArrayMaxSize, ArrayMinSize, IsDefined, IsString, IsUrl, MinLength } from 'class-validator';
import { ArrayMaxSize, ArrayMinSize, IsDefined, IsOptional, IsString, IsUrl, MinLength, ValidateIf } from 'class-validator';
import { Type } from 'class-transformer';
export class CreateAgencyLogoDto {
@IsString()
@IsDefined()
id: string;
path: string;
}
export class CreateAgencyDto {
@IsString()
@MinLength(3)
@ -10,25 +18,31 @@ export class CreateAgencyDto {
website: string;
@IsUrl()
@ValidateIf((o) => o.facebook)
facebook: string;
@IsString()
@IsOptional()
instagram: string;
@IsString()
@IsOptional()
twitter: string;
@IsUrl()
linkedin: string;
@ValidateIf((o) => o.linkedIn)
linkedIn: string;
@IsUrl()
@ValidateIf((o) => o.youtube)
youtube: string;
@IsUrl()
@IsString()
@IsOptional()
tiktok: string;
@IsString()
logo: string;
@Type(() => CreateAgencyLogoDto)
logo: CreateAgencyLogoDto;
@IsString()
shortDescription: string;
@ -41,5 +55,5 @@ export class CreateAgencyDto {
})
@ArrayMinSize(1)
@ArrayMaxSize(3)
niche: string[];
niches: string[];
}

View File

@ -13,7 +13,7 @@ export class EmailService {
console.log('Sending email to', to);
const sends = await resend.emails.send({
from: process.env.IS_GENERAL === 'true' ? 'Nevo <nevo@postiz.com>' : 'Nevo <nevo@gitroom.com>',
from: process.env.IS_GENERAL === 'true' ? 'Nevo <nevo@postiz.com>' : 'Nevo <nevo@postiz.com>',
to,
subject,
html,