feat: merge
This commit is contained in:
commit
7e8b6c87f4
|
|
@ -26,6 +26,8 @@ import { OpenaiService } from '@gitroom/nestjs-libraries/openai/openai.service';
|
||||||
import { ExtractContentService } from '@gitroom/nestjs-libraries/openai/extract.content.service';
|
import { ExtractContentService } from '@gitroom/nestjs-libraries/openai/extract.content.service';
|
||||||
import { CodesService } from '@gitroom/nestjs-libraries/services/codes.service';
|
import { CodesService } from '@gitroom/nestjs-libraries/services/codes.service';
|
||||||
import { CopilotController } from '@gitroom/backend/api/routes/copilot.controller';
|
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 = [
|
const authenticatedController = [
|
||||||
UsersController,
|
UsersController,
|
||||||
|
|
@ -40,6 +42,7 @@ const authenticatedController = [
|
||||||
MarketplaceController,
|
MarketplaceController,
|
||||||
MessagesController,
|
MessagesController,
|
||||||
CopilotController,
|
CopilotController,
|
||||||
|
AgenciesController,
|
||||||
];
|
];
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
|
@ -60,7 +63,7 @@ const authenticatedController = [
|
||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
],
|
],
|
||||||
controllers: [StripeController, AuthController, ...authenticatedController],
|
controllers: [StripeController, AuthController, PublicController, ...authenticatedController],
|
||||||
providers: [
|
providers: [
|
||||||
AuthService,
|
AuthService,
|
||||||
StripeService,
|
StripeService,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
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';
|
||||||
|
import { GetUserFromRequest } from '@gitroom/nestjs-libraries/user/user.from.request';
|
||||||
|
import { CreateAgencyDto } from '@gitroom/nestjs-libraries/dtos/agencies/create.agency.dto';
|
||||||
|
|
||||||
|
@ApiTags('Agencies')
|
||||||
|
@Controller('/agencies')
|
||||||
|
export class AgenciesController {
|
||||||
|
constructor(private _agenciesService: AgenciesService) {}
|
||||||
|
@Get('/')
|
||||||
|
async getAgencyByUser(@GetUserFromRequest() user: User) {
|
||||||
|
return this._agenciesService.getAgencyByUser(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/')
|
||||||
|
async createAgency(
|
||||||
|
@GetUserFromRequest() user: User,
|
||||||
|
@Body() body: CreateAgencyDto
|
||||||
|
) {
|
||||||
|
return this._agenciesService.createAgency(user, body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,8 @@ export const dynamic = 'force-dynamic';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
import loadDynamic from 'next/dynamic';
|
||||||
|
const ReturnUrlComponent = loadDynamic(() => import('./return.url.component'));
|
||||||
|
|
||||||
export default async function AuthLayout({
|
export default async function AuthLayout({
|
||||||
children,
|
children,
|
||||||
|
|
@ -13,6 +15,7 @@ export default async function AuthLayout({
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<ReturnUrlComponent />
|
||||||
<div className="absolute left-0 top-0 z-[0] h-[100vh] w-[100vw] overflow-hidden bg-loginBg bg-contain bg-no-repeat bg-left-top" />
|
<div className="absolute left-0 top-0 z-[0] h-[100vh] w-[100vw] overflow-hidden bg-loginBg bg-contain bg-no-repeat bg-left-top" />
|
||||||
<div className="relative z-[1] pr-[100px] flex justify-end items-center h-[100vh] w-[100vw] overflow-hidden">
|
<div className="relative z-[1] pr-[100px] flex justify-end items-center h-[100vh] w-[100vw] overflow-hidden">
|
||||||
<div className="w-[557px] flex h-[614px] bg-loginBox bg-contain">
|
<div className="w-[557px] flex h-[614px] bg-loginBox bg-contain">
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
'use client';
|
||||||
|
import { useSearchParams } from 'next/navigation';
|
||||||
|
import { useCallback, useEffect } from 'react';
|
||||||
|
|
||||||
|
const ReturnUrlComponent = () => {
|
||||||
|
const params = useSearchParams();
|
||||||
|
const url = params.get('returnUrl');
|
||||||
|
useEffect(() => {
|
||||||
|
if (url?.indexOf?.('http')! > -1) {
|
||||||
|
localStorage.setItem('returnUrl', url!);
|
||||||
|
}
|
||||||
|
}, [url]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useReturnUrl = () => {
|
||||||
|
return {
|
||||||
|
getAndClear: useCallback(() => {
|
||||||
|
const data = localStorage.getItem('returnUrl');
|
||||||
|
localStorage.removeItem('returnUrl');
|
||||||
|
return data;
|
||||||
|
}, [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ReturnUrlComponent;
|
||||||
|
|
@ -4,6 +4,7 @@ import { ReactNode, useCallback } from 'react';
|
||||||
import { FetchWrapperComponent } from '@gitroom/helpers/utils/custom.fetch';
|
import { FetchWrapperComponent } from '@gitroom/helpers/utils/custom.fetch';
|
||||||
import { deleteDialog } from '@gitroom/react/helpers/delete.dialog';
|
import { deleteDialog } from '@gitroom/react/helpers/delete.dialog';
|
||||||
import { isGeneral } from '@gitroom/react/helpers/is.general';
|
import { isGeneral } from '@gitroom/react/helpers/is.general';
|
||||||
|
import { useReturnUrl } from '@gitroom/frontend/app/auth/return.url.component';
|
||||||
|
|
||||||
export default function LayoutContext(params: { children: ReactNode }) {
|
export default function LayoutContext(params: { children: ReactNode }) {
|
||||||
if (params?.children) {
|
if (params?.children) {
|
||||||
|
|
@ -14,16 +15,33 @@ export default function LayoutContext(params: { children: ReactNode }) {
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
function LayoutContextInner(params: { children: ReactNode }) {
|
function LayoutContextInner(params: { children: ReactNode }) {
|
||||||
|
const returnUrl = useReturnUrl();
|
||||||
|
|
||||||
const afterRequest = useCallback(
|
const afterRequest = useCallback(
|
||||||
async (url: string, options: RequestInit, response: Response) => {
|
async (url: string, options: RequestInit, response: Response) => {
|
||||||
|
const reloadOrOnboarding =
|
||||||
|
response?.headers?.get('reload') ||
|
||||||
|
response?.headers?.get('onboarding');
|
||||||
|
|
||||||
|
if (reloadOrOnboarding) {
|
||||||
|
const getAndClear = returnUrl.getAndClear();
|
||||||
|
if (getAndClear) {
|
||||||
|
window.location.href = getAndClear;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (response?.headers?.get('onboarding')) {
|
if (response?.headers?.get('onboarding')) {
|
||||||
window.location.href = isGeneral()
|
window.location.href = isGeneral()
|
||||||
? '/launches?onboarding=true'
|
? '/launches?onboarding=true'
|
||||||
: '/analytics?onboarding=true';
|
: '/analytics?onboarding=true';
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response?.headers?.get('reload')) {
|
if (response?.headers?.get('reload')) {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.status === 401) {
|
if (response.status === 401) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,154 @@
|
||||||
|
import { PrismaRepository } from '@gitroom/nestjs-libraries/database/prisma/prisma.service';
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { User } from '@prisma/client';
|
||||||
|
import { CreateAgencyDto } from '@gitroom/nestjs-libraries/dtos/agencies/create.agency.dto';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AgenciesRepository {
|
||||||
|
constructor(
|
||||||
|
private _socialMediaAgencies: PrismaRepository<'socialMediaAgency'>,
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async createAgency(user: User, body: CreateAgencyDto) {
|
||||||
|
const insertAgency =
|
||||||
|
await this._socialMediaAgencies.model.socialMediaAgency.upsert({
|
||||||
|
where: {
|
||||||
|
userId: user.id,
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
userId: user.id,
|
||||||
|
name: body.name,
|
||||||
|
website: body.website,
|
||||||
|
facebook: body.facebook,
|
||||||
|
instagram: body.instagram,
|
||||||
|
twitter: body.twitter,
|
||||||
|
linkedIn: body.linkedIn,
|
||||||
|
youtube: body.youtube,
|
||||||
|
tiktok: body.tiktok,
|
||||||
|
logoId: body.logo.id,
|
||||||
|
shortDescription: body.shortDescription,
|
||||||
|
description: body.description,
|
||||||
|
approved: false,
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
userId: user.id,
|
||||||
|
name: body.name,
|
||||||
|
website: body.website,
|
||||||
|
facebook: body.facebook,
|
||||||
|
instagram: body.instagram,
|
||||||
|
twitter: body.twitter,
|
||||||
|
linkedIn: body.linkedIn,
|
||||||
|
youtube: body.youtube,
|
||||||
|
tiktok: body.tiktok,
|
||||||
|
logoId: body.logo.id,
|
||||||
|
shortDescription: body.shortDescription,
|
||||||
|
description: body.description,
|
||||||
|
slug: body.name.toLowerCase().replace(/ /g, '-'),
|
||||||
|
approved: false,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await this._socialMediaAgenciesNiche.model.socialMediaAgencyNiche.deleteMany(
|
||||||
|
{
|
||||||
|
where: {
|
||||||
|
agencyId: insertAgency.id,
|
||||||
|
niche: {
|
||||||
|
notIn: body.niches,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const currentNiche =
|
||||||
|
await this._socialMediaAgenciesNiche.model.socialMediaAgencyNiche.findMany(
|
||||||
|
{
|
||||||
|
where: {
|
||||||
|
agencyId: insertAgency.id,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
niche: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const addNewNiche = body.niches.filter(
|
||||||
|
(n) => !currentNiche.some((c) => c.niche === n)
|
||||||
|
);
|
||||||
|
|
||||||
|
await this._socialMediaAgenciesNiche.model.socialMediaAgencyNiche.createMany(
|
||||||
|
{
|
||||||
|
data: addNewNiche.map((n) => ({
|
||||||
|
agencyId: insertAgency.id,
|
||||||
|
niche: n,
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return insertAgency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,165 @@
|
||||||
|
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,
|
||||||
|
private _emailService: EmailService
|
||||||
|
) {}
|
||||||
|
getAgencyByUser(user: User) {
|
||||||
|
return this._agenciesRepository.getAgencyByUser(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;">© 2024 Your Gitroom Limited All rights reserved.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
return agency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -27,6 +27,8 @@ import { MessagesRepository } from '@gitroom/nestjs-libraries/database/prisma/ma
|
||||||
import { StripeService } from '@gitroom/nestjs-libraries/services/stripe.service';
|
import { StripeService } from '@gitroom/nestjs-libraries/services/stripe.service';
|
||||||
import { ExtractContentService } from '@gitroom/nestjs-libraries/openai/extract.content.service';
|
import { ExtractContentService } from '@gitroom/nestjs-libraries/openai/extract.content.service';
|
||||||
import { OpenaiService } from '@gitroom/nestjs-libraries/openai/openai.service';
|
import { OpenaiService } from '@gitroom/nestjs-libraries/openai/openai.service';
|
||||||
|
import { AgenciesService } from '@gitroom/nestjs-libraries/database/prisma/agencies/agencies.service';
|
||||||
|
import { AgenciesRepository } from '@gitroom/nestjs-libraries/database/prisma/agencies/agencies.repository';
|
||||||
|
|
||||||
@Global()
|
@Global()
|
||||||
@Module({
|
@Module({
|
||||||
|
|
@ -55,6 +57,8 @@ import { OpenaiService } from '@gitroom/nestjs-libraries/openai/openai.service';
|
||||||
MediaRepository,
|
MediaRepository,
|
||||||
CommentsRepository,
|
CommentsRepository,
|
||||||
ItemUserRepository,
|
ItemUserRepository,
|
||||||
|
AgenciesService,
|
||||||
|
AgenciesRepository,
|
||||||
ItemUserService,
|
ItemUserService,
|
||||||
MessagesService,
|
MessagesService,
|
||||||
CommentsService,
|
CommentsService,
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ model User {
|
||||||
orderSeller Orders[] @relation("orderSeller")
|
orderSeller Orders[] @relation("orderSeller")
|
||||||
payoutProblems PayoutProblems[]
|
payoutProblems PayoutProblems[]
|
||||||
lastOnline DateTime @default(now())
|
lastOnline DateTime @default(now())
|
||||||
|
agencies SocialMediaAgency[]
|
||||||
|
|
||||||
@@unique([email, providerName])
|
@@unique([email, providerName])
|
||||||
@@index([lastReadNotifications])
|
@@index([lastReadNotifications])
|
||||||
|
|
@ -165,10 +166,51 @@ model Media {
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
userPicture User[]
|
userPicture User[]
|
||||||
|
agencies SocialMediaAgency[]
|
||||||
|
|
||||||
@@index([organizationId])
|
@@index([organizationId])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model SocialMediaAgency {
|
||||||
|
id String @id @default(uuid())
|
||||||
|
user User @relation(fields: [userId], references: [id])
|
||||||
|
userId String @unique()
|
||||||
|
name String
|
||||||
|
logoId String?
|
||||||
|
logo Media? @relation(fields: [logoId], references: [id])
|
||||||
|
website String?
|
||||||
|
slug String?
|
||||||
|
|
||||||
|
facebook String?
|
||||||
|
instagram String?
|
||||||
|
twitter String?
|
||||||
|
linkedIn String?
|
||||||
|
youtube String?
|
||||||
|
tiktok String?
|
||||||
|
otherSocialMedia String?
|
||||||
|
|
||||||
|
shortDescription String
|
||||||
|
description String
|
||||||
|
niches SocialMediaAgencyNiche[]
|
||||||
|
approved Boolean @default(false)
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
deletedAt DateTime?
|
||||||
|
|
||||||
|
@@index([userId])
|
||||||
|
@@index([deletedAt])
|
||||||
|
@@index([id])
|
||||||
|
}
|
||||||
|
|
||||||
|
model SocialMediaAgencyNiche {
|
||||||
|
agencyId String
|
||||||
|
agency SocialMediaAgency @relation(fields: [agencyId], references: [id])
|
||||||
|
niche String
|
||||||
|
|
||||||
|
@@id([agencyId, niche])
|
||||||
|
}
|
||||||
|
|
||||||
model Credits {
|
model Credits {
|
||||||
id String @id @default(uuid())
|
id String @id @default(uuid())
|
||||||
organization Organization @relation(fields: [organizationId], references: [id])
|
organization Organization @relation(fields: [organizationId], references: [id])
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
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)
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@IsUrl()
|
||||||
|
@IsDefined()
|
||||||
|
website: string;
|
||||||
|
|
||||||
|
@IsUrl()
|
||||||
|
@ValidateIf((o) => o.facebook)
|
||||||
|
facebook: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
instagram: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
twitter: string;
|
||||||
|
|
||||||
|
@IsUrl()
|
||||||
|
@ValidateIf((o) => o.linkedIn)
|
||||||
|
linkedIn: string;
|
||||||
|
|
||||||
|
@IsUrl()
|
||||||
|
@ValidateIf((o) => o.youtube)
|
||||||
|
youtube: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
tiktok: string;
|
||||||
|
|
||||||
|
@Type(() => CreateAgencyLogoDto)
|
||||||
|
logo: CreateAgencyLogoDto;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
shortDescription: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
description: string;
|
||||||
|
|
||||||
|
@IsString({
|
||||||
|
each: true
|
||||||
|
})
|
||||||
|
@ArrayMinSize(1)
|
||||||
|
@ArrayMaxSize(3)
|
||||||
|
niches: string[];
|
||||||
|
}
|
||||||
|
|
@ -13,7 +13,7 @@ export class EmailService {
|
||||||
|
|
||||||
console.log('Sending email to', to);
|
console.log('Sending email to', to);
|
||||||
const sends = await resend.emails.send({
|
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,
|
to,
|
||||||
subject,
|
subject,
|
||||||
html,
|
html,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue