feat: agencies
This commit is contained in:
parent
84e22203d9
commit
728a2a7a78
|
|
@ -1,8 +1,9 @@
|
|||
import { Controller, Get } from '@nestjs/common';
|
||||
import { 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')
|
||||
|
|
@ -12,4 +13,9 @@ export class AgenciesController {
|
|||
async generateImage(@GetUserFromRequest() user: User) {
|
||||
return this._agenciesService.getAgencyByUser(user);
|
||||
}
|
||||
|
||||
@Post('/')
|
||||
async createAgency(@GetUserFromRequest() user: User, body: CreateAgencyDto) {
|
||||
return this._agenciesService.createAgency(user, body);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ export const dynamic = 'force-dynamic';
|
|||
import { ReactNode } from 'react';
|
||||
import Image from 'next/image';
|
||||
import clsx from 'clsx';
|
||||
import loadDynamic from 'next/dynamic';
|
||||
const ReturnUrlComponent = loadDynamic(() => import('./return.url.component'));
|
||||
|
||||
export default async function AuthLayout({
|
||||
children,
|
||||
|
|
@ -13,6 +15,7 @@ export default async function AuthLayout({
|
|||
}) {
|
||||
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="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">
|
||||
|
|
|
|||
|
|
@ -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 { deleteDialog } from '@gitroom/react/helpers/delete.dialog';
|
||||
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 }) {
|
||||
if (params?.children) {
|
||||
|
|
@ -14,16 +15,33 @@ export default function LayoutContext(params: { children: ReactNode }) {
|
|||
return <></>;
|
||||
}
|
||||
function LayoutContextInner(params: { children: ReactNode }) {
|
||||
const returnUrl = useReturnUrl();
|
||||
|
||||
const afterRequest = useCallback(
|
||||
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')) {
|
||||
window.location.href = isGeneral()
|
||||
? '/launches?onboarding=true'
|
||||
: '/analytics?onboarding=true';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (response?.headers?.get('reload')) {
|
||||
window.location.reload();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (response.status === 401) {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
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 _socialMediaAgencies: PrismaRepository<'socialMediaAgency'>,
|
||||
private _socialMediaAgenciesNiche: PrismaRepository<'socialMediaAgencyNiche'>
|
||||
) {}
|
||||
|
||||
getAgencyByUser(user: User) {
|
||||
|
|
@ -16,4 +18,87 @@ export class AgenciesRepository {
|
|||
},
|
||||
});
|
||||
}
|
||||
|
||||
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,
|
||||
shortDescription: body.shortDescription,
|
||||
description: body.description,
|
||||
niches: {
|
||||
create: body.niche.map((n) => ({
|
||||
niche: n,
|
||||
})),
|
||||
},
|
||||
},
|
||||
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,
|
||||
shortDescription: body.shortDescription,
|
||||
description: body.description,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
await this._socialMediaAgenciesNiche.model.socialMediaAgencyNiche.deleteMany(
|
||||
{
|
||||
where: {
|
||||
agencyId: insertAgency.id,
|
||||
niche: {
|
||||
notIn: body.niche,
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const currentNiche =
|
||||
await this._socialMediaAgenciesNiche.model.socialMediaAgencyNiche.findMany(
|
||||
{
|
||||
where: {
|
||||
agencyId: insertAgency.id,
|
||||
},
|
||||
select: {
|
||||
niche: true,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const addNewNiche = body.niche.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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
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';
|
||||
|
||||
@Injectable()
|
||||
export class AgenciesService {
|
||||
|
|
@ -8,4 +9,8 @@ export class AgenciesService {
|
|||
getAgencyByUser(user: User) {
|
||||
return this._agenciesRepository.getAgencyByUser(user);
|
||||
}
|
||||
|
||||
createAgency(user: User, body: CreateAgencyDto) {
|
||||
return this._agenciesRepository.createAgency(user, body);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,14 +174,10 @@ model Media {
|
|||
model SocialMediaAgency {
|
||||
id String @id @default(uuid())
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
userId String
|
||||
userId String @unique()
|
||||
name String
|
||||
logoId String?
|
||||
logo Media? @relation(fields: [logoId], references: [id])
|
||||
tagline String?
|
||||
address String?
|
||||
phoneNumber String?
|
||||
emailAddress String?
|
||||
website String?
|
||||
|
||||
facebook String?
|
||||
|
|
@ -189,30 +185,13 @@ model SocialMediaAgency {
|
|||
twitter String?
|
||||
linkedIn String?
|
||||
youtube String?
|
||||
tiktok String?
|
||||
otherSocialMedia String?
|
||||
|
||||
primaryServices String
|
||||
specialties String?
|
||||
packages String?
|
||||
caseStudies String?
|
||||
|
||||
yearEstablished Int?
|
||||
teamSize Int?
|
||||
languagesSupported String?
|
||||
clientTypes String?
|
||||
clientTestimonials String?
|
||||
|
||||
certifications String?
|
||||
awards String?
|
||||
|
||||
blog String?
|
||||
faqs String?
|
||||
events String?
|
||||
freeConsultation Boolean @default(false)
|
||||
|
||||
businessHours String?
|
||||
serviceArea String?
|
||||
termsAndConditions String?
|
||||
shortDescription String
|
||||
description String
|
||||
niches SocialMediaAgencyNiche[]
|
||||
approved Boolean @default(false)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
|
@ -223,6 +202,14 @@ model SocialMediaAgency {
|
|||
@@index([id])
|
||||
}
|
||||
|
||||
model SocialMediaAgencyNiche {
|
||||
agencyId String
|
||||
agency SocialMediaAgency @relation(fields: [agencyId], references: [id])
|
||||
niche String
|
||||
|
||||
@@id([agencyId, niche])
|
||||
}
|
||||
|
||||
model Credits {
|
||||
id String @id @default(uuid())
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
import { IsDefined, IsString, IsUrl, MinLength } from 'class-validator';
|
||||
|
||||
export class CreateAgencyDto {
|
||||
@IsString()
|
||||
@MinLength(3)
|
||||
name: string;
|
||||
|
||||
@IsUrl()
|
||||
@IsDefined()
|
||||
website: string;
|
||||
|
||||
@IsUrl()
|
||||
facebook: string;
|
||||
|
||||
@IsString()
|
||||
instagram: string;
|
||||
|
||||
@IsString()
|
||||
twitter: string;
|
||||
|
||||
@IsUrl()
|
||||
linkedin: string;
|
||||
|
||||
@IsUrl()
|
||||
youtube: string;
|
||||
|
||||
@IsUrl()
|
||||
tiktok: string;
|
||||
|
||||
@IsString()
|
||||
logo: string;
|
||||
|
||||
@IsString()
|
||||
shortDescription: string;
|
||||
|
||||
@IsString()
|
||||
description: string;
|
||||
|
||||
@IsString({
|
||||
each: true
|
||||
})
|
||||
niche: string[];
|
||||
}
|
||||
Loading…
Reference in New Issue