feat: preview
This commit is contained in:
commit
396a55f36f
|
|
@ -26,6 +26,7 @@ import { CopilotController } from '@gitroom/backend/api/routes/copilot.controlle
|
|||
import { AgenciesController } from '@gitroom/backend/api/routes/agencies.controller';
|
||||
import { PublicController } from '@gitroom/backend/api/routes/public.controller';
|
||||
import { RootController } from '@gitroom/backend/api/routes/root.controller';
|
||||
import { TrackService } from '@gitroom/nestjs-libraries/track/track.service';
|
||||
|
||||
const authenticatedController = [
|
||||
UsersController,
|
||||
|
|
@ -63,6 +64,7 @@ const authenticatedController = [
|
|||
PermissionsService,
|
||||
CodesService,
|
||||
IntegrationManager,
|
||||
TrackService,
|
||||
],
|
||||
get exports() {
|
||||
return [...this.imports, ...this.providers];
|
||||
|
|
|
|||
|
|
@ -1,4 +1,13 @@
|
|||
import { Body, Controller, Get, Param, Post, Req, Res } from '@nestjs/common';
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Get,
|
||||
Ip,
|
||||
Param,
|
||||
Post,
|
||||
Req,
|
||||
Res,
|
||||
} from '@nestjs/common';
|
||||
import { Response, Request } from 'express';
|
||||
|
||||
import { CreateOrgUserDto } from '@gitroom/nestjs-libraries/dtos/auth/create.org.user.dto';
|
||||
|
|
@ -9,6 +18,8 @@ import { ForgotPasswordDto } from '@gitroom/nestjs-libraries/dtos/auth/forgot.pa
|
|||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { getCookieUrlFromDomain } from '@gitroom/helpers/subdomain/subdomain.management';
|
||||
import { EmailService } from '@gitroom/nestjs-libraries/services/email.service';
|
||||
import { RealIP } from 'nestjs-real-ip';
|
||||
import { UserAgent } from '@gitroom/nestjs-libraries/user/user.agent';
|
||||
|
||||
@ApiTags('Auth')
|
||||
@Controller('/auth')
|
||||
|
|
@ -21,7 +32,9 @@ export class AuthController {
|
|||
async register(
|
||||
@Req() req: Request,
|
||||
@Body() body: CreateOrgUserDto,
|
||||
@Res({ passthrough: true }) response: Response
|
||||
@Res({ passthrough: true }) response: Response,
|
||||
@RealIP() ip: string,
|
||||
@UserAgent() userAgent: string
|
||||
) {
|
||||
try {
|
||||
const getOrgFromCookie = this._authService.getOrgFromCookie(
|
||||
|
|
@ -31,10 +44,13 @@ export class AuthController {
|
|||
const { jwt, addedOrg } = await this._authService.routeAuth(
|
||||
body.provider,
|
||||
body,
|
||||
ip,
|
||||
userAgent,
|
||||
getOrgFromCookie
|
||||
);
|
||||
|
||||
const activationRequired = body.provider === 'LOCAL' && this._emailService.hasProvider();
|
||||
const activationRequired =
|
||||
body.provider === 'LOCAL' && this._emailService.hasProvider();
|
||||
|
||||
if (activationRequired) {
|
||||
response.header('activate', 'true');
|
||||
|
|
@ -73,7 +89,9 @@ export class AuthController {
|
|||
async login(
|
||||
@Req() req: Request,
|
||||
@Body() body: LoginUserDto,
|
||||
@Res({ passthrough: true }) response: Response
|
||||
@Res({ passthrough: true }) response: Response,
|
||||
@RealIP() ip: string,
|
||||
@UserAgent() userAgent: string
|
||||
) {
|
||||
try {
|
||||
const getOrgFromCookie = this._authService.getOrgFromCookie(
|
||||
|
|
@ -83,6 +101,8 @@ export class AuthController {
|
|||
const { jwt, addedOrg } = await this._authService.routeAuth(
|
||||
body.provider,
|
||||
body,
|
||||
ip,
|
||||
userAgent,
|
||||
getOrgFromCookie
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Body, Controller, Get, Param, Post } from '@nestjs/common';
|
||||
import { Body, Controller, Get, Param, Post, Req } from '@nestjs/common';
|
||||
import { SubscriptionService } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/subscription.service';
|
||||
import { StripeService } from '@gitroom/nestjs-libraries/services/stripe.service';
|
||||
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request';
|
||||
|
|
@ -7,6 +7,7 @@ import { BillingSubscribeDto } from '@gitroom/nestjs-libraries/dtos/billing/bill
|
|||
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';
|
||||
import { Request } from 'express';
|
||||
|
||||
@ApiTags('Billing')
|
||||
@Controller('/billing')
|
||||
|
|
@ -23,19 +24,22 @@ export class BillingController {
|
|||
@Param('id') body: string
|
||||
) {
|
||||
return {
|
||||
exists: !!(await this._subscriptionService.checkSubscription(
|
||||
status: await this._stripeService.checkSubscription(
|
||||
org.id,
|
||||
body
|
||||
)),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@Post('/subscribe')
|
||||
subscribe(
|
||||
@GetOrgFromRequest() org: Organization,
|
||||
@Body() body: BillingSubscribeDto
|
||||
@GetUserFromRequest() user: User,
|
||||
@Body() body: BillingSubscribeDto,
|
||||
@Req() req: Request
|
||||
) {
|
||||
return this._stripeService.subscribe(org.id, body);
|
||||
const uniqueId = req?.cookies?.track;
|
||||
return this._stripeService.subscribe(uniqueId, org.id, user.id, body, org.allowTrial);
|
||||
}
|
||||
|
||||
@Get('/portal')
|
||||
|
|
|
|||
|
|
@ -1,15 +1,24 @@
|
|||
import { Controller, Get, Param } from '@nestjs/common';
|
||||
import { Body, Controller, Get, Param, Post, Req, Res } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { AgenciesService } from '@gitroom/nestjs-libraries/database/prisma/agencies/agencies.service';
|
||||
import { PostsService } from '@gitroom/nestjs-libraries/database/prisma/posts/posts.service';
|
||||
import { TrackService } from '@gitroom/nestjs-libraries/track/track.service';
|
||||
import { RealIP } from 'nestjs-real-ip';
|
||||
import { UserAgent } from '@gitroom/nestjs-libraries/user/user.agent';
|
||||
import { TrackEnum } from '@gitroom/nestjs-libraries/user/track.enum';
|
||||
import { Request, Response } from 'express';
|
||||
import { makeId } from '@gitroom/nestjs-libraries/services/make.is';
|
||||
import { getCookieUrlFromDomain } from '@gitroom/helpers/subdomain/subdomain.management';
|
||||
|
||||
@ApiTags('Public')
|
||||
@Controller('/public')
|
||||
export class PublicController {
|
||||
constructor(
|
||||
private _agenciesService: AgenciesService,
|
||||
private _postsService: PostsService
|
||||
private _postsService: PostsService,
|
||||
private _trackService: TrackService
|
||||
) {}
|
||||
|
||||
@Get('/agencies-list')
|
||||
async getAgencyByUser() {
|
||||
return this._agenciesService.getAllAgencies();
|
||||
|
|
@ -49,4 +58,48 @@ export class PublicController {
|
|||
})
|
||||
);
|
||||
}
|
||||
|
||||
@Post('/t')
|
||||
async trackEvent(
|
||||
@Res() res: Response,
|
||||
@Req() req: Request,
|
||||
@RealIP() ip: string,
|
||||
@UserAgent() userAgent: string,
|
||||
@Body()
|
||||
body: { fbclid?: string; tt: TrackEnum; additional: Record<string, any> }
|
||||
) {
|
||||
const uniqueId = req?.cookies?.track || makeId(10);
|
||||
const fbclid = req?.cookies?.fbclid || body.fbclid;
|
||||
await this._trackService.track(
|
||||
uniqueId,
|
||||
ip,
|
||||
userAgent,
|
||||
body.tt,
|
||||
body.additional,
|
||||
fbclid
|
||||
);
|
||||
if (!req.cookies.track) {
|
||||
res.cookie('track', uniqueId, {
|
||||
domain: getCookieUrlFromDomain(process.env.FRONTEND_URL!),
|
||||
secure: true,
|
||||
httpOnly: true,
|
||||
sameSite: 'none',
|
||||
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365),
|
||||
});
|
||||
}
|
||||
|
||||
if (body.fbclid && !req.cookies.fbclid) {
|
||||
res.cookie('fbclid', body.fbclid, {
|
||||
domain: getCookieUrlFromDomain(process.env.FRONTEND_URL!),
|
||||
secure: true,
|
||||
httpOnly: true,
|
||||
sameSite: 'none',
|
||||
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365),
|
||||
});
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
track: uniqueId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,11 +54,13 @@ export class StripeController {
|
|||
// Maybe it comes from another stripe webhook
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
if (event?.data?.object?.metadata?.service !== 'gitroom') {
|
||||
if (event?.data?.object?.metadata?.service !== 'gitroom' && event.type !== 'invoice.payment_succeeded') {
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
switch (event.type) {
|
||||
case 'invoice.payment_succeeded':
|
||||
return this._stripeService.paymentSucceeded(event);
|
||||
case 'checkout.session.completed':
|
||||
return this._stripeService.updateOrder(event);
|
||||
case 'account.updated':
|
||||
|
|
|
|||
|
|
@ -27,6 +27,11 @@ import { ApiTags } from '@nestjs/swagger';
|
|||
import { UsersService } from '@gitroom/nestjs-libraries/database/prisma/users/users.service';
|
||||
import { UserDetailDto } from '@gitroom/nestjs-libraries/dtos/users/user.details.dto';
|
||||
import { HttpForbiddenException } from '@gitroom/nestjs-libraries/services/exception.filter';
|
||||
import { RealIP } from 'nestjs-real-ip';
|
||||
import { UserAgent } from '@gitroom/nestjs-libraries/user/user.agent';
|
||||
import { TrackEnum } from '@gitroom/nestjs-libraries/user/track.enum';
|
||||
import { TrackService } from '@gitroom/nestjs-libraries/track/track.service';
|
||||
import { makeId } from '@gitroom/nestjs-libraries/services/make.is';
|
||||
|
||||
@ApiTags('User')
|
||||
@Controller('/user')
|
||||
|
|
@ -36,7 +41,8 @@ export class UsersController {
|
|||
private _stripeService: StripeService,
|
||||
private _authService: AuthService,
|
||||
private _orgService: OrganizationService,
|
||||
private _userService: UsersService
|
||||
private _userService: UsersService,
|
||||
private _trackService: TrackService
|
||||
) {}
|
||||
@Get('/self')
|
||||
async getSelf(
|
||||
|
|
@ -54,15 +60,19 @@ export class UsersController {
|
|||
// @ts-ignore
|
||||
totalChannels: organization?.subscription?.totalChannels || pricing.FREE.channel,
|
||||
// @ts-ignore
|
||||
tier: organization?.subscription?.subscriptionTier || (!process.env.STRIPE_PUBLISHABLE_KEY ? 'ULTIMATE' : 'FREE'),
|
||||
tier: organization?.subscription?.subscriptionTier ||
|
||||
(!process.env.STRIPE_PUBLISHABLE_KEY ? 'ULTIMATE' : 'FREE'),
|
||||
// @ts-ignore
|
||||
role: organization?.users[0]?.role,
|
||||
// @ts-ignore
|
||||
isLifetime: !!organization?.subscription?.isLifetime,
|
||||
admin: !!user.isSuperAdmin,
|
||||
impersonate: !!req.cookies.impersonate,
|
||||
allowTrial: organization?.allowTrial,
|
||||
// @ts-ignore
|
||||
publicApi: (organization?.users[0]?.role === 'SUPERADMIN' || organization?.users[0]?.role === 'ADMIN') ? organization?.apiKey : '',
|
||||
publicApi: organization?.users[0]?.role === 'SUPERADMIN' || organization?.users[0]?.role === 'ADMIN'
|
||||
? organization?.apiKey
|
||||
: '',
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -205,4 +215,32 @@ export class UsersController {
|
|||
|
||||
response.status(200).send();
|
||||
}
|
||||
|
||||
@Post('/t')
|
||||
async trackEvent(
|
||||
@Res({ passthrough: true }) res: Response,
|
||||
@Req() req: Request,
|
||||
@GetUserFromRequest() user: User,
|
||||
@RealIP() ip: string,
|
||||
@UserAgent() userAgent: string,
|
||||
@Body() body: { tt: TrackEnum; fbclid: string, additional: Record<string, any> }
|
||||
) {
|
||||
const uniqueId = req?.cookies?.track || makeId(10);
|
||||
const fbclid = req?.cookies?.fbclid || body.fbclid;
|
||||
await this._trackService.track(uniqueId, ip, userAgent, body.tt, body.additional, fbclid, user);
|
||||
if (!req.cookies.track) {
|
||||
res.cookie('track', uniqueId, {
|
||||
domain: getCookieUrlFromDomain(process.env.FRONTEND_URL!),
|
||||
secure: true,
|
||||
httpOnly: true,
|
||||
sameSite: 'none',
|
||||
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365),
|
||||
});
|
||||
}
|
||||
|
||||
console.log('hello');
|
||||
res.status(200).json({
|
||||
track: uniqueId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,11 +18,13 @@ export class AuthService {
|
|||
private _userService: UsersService,
|
||||
private _organizationService: OrganizationService,
|
||||
private _notificationService: NotificationService,
|
||||
private _emailService: EmailService,
|
||||
private _emailService: EmailService
|
||||
) {}
|
||||
async routeAuth(
|
||||
provider: Provider,
|
||||
body: CreateOrgUserDto | LoginUserDto,
|
||||
ip: string,
|
||||
userAgent: string,
|
||||
addToOrg?: boolean | { orgId: string; role: 'USER' | 'ADMIN'; id: string }
|
||||
) {
|
||||
if (provider === Provider.LOCAL) {
|
||||
|
|
@ -32,7 +34,11 @@ export class AuthService {
|
|||
throw new Error('User already exists');
|
||||
}
|
||||
|
||||
const create = await this._organizationService.createOrgAndUser(body);
|
||||
const create = await this._organizationService.createOrgAndUser(
|
||||
body,
|
||||
ip,
|
||||
userAgent
|
||||
);
|
||||
|
||||
const addedOrg =
|
||||
addToOrg && typeof addToOrg !== 'boolean'
|
||||
|
|
@ -45,7 +51,11 @@ export class AuthService {
|
|||
: false;
|
||||
|
||||
const obj = { addedOrg, jwt: await this.jwt(create.users[0].user) };
|
||||
await this._emailService.sendEmail(body.email, 'Activate your account', `Click <a href="${process.env.FRONTEND_URL}/auth/activate/${obj.jwt}">here</a> to activate your account`);
|
||||
await this._emailService.sendEmail(
|
||||
body.email,
|
||||
'Activate your account',
|
||||
`Click <a href="${process.env.FRONTEND_URL}/auth/activate/${obj.jwt}">here</a> to activate your account`
|
||||
);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
|
@ -62,7 +72,9 @@ export class AuthService {
|
|||
|
||||
const user = await this.loginOrRegisterProvider(
|
||||
provider,
|
||||
body as CreateOrgUserDto
|
||||
body as CreateOrgUserDto,
|
||||
ip,
|
||||
userAgent
|
||||
);
|
||||
|
||||
const addedOrg =
|
||||
|
|
@ -101,7 +113,9 @@ export class AuthService {
|
|||
|
||||
private async loginOrRegisterProvider(
|
||||
provider: Provider,
|
||||
body: CreateOrgUserDto
|
||||
body: CreateOrgUserDto,
|
||||
ip: string,
|
||||
userAgent: string
|
||||
) {
|
||||
const providerInstance = ProvidersFactory.loadProvider(provider);
|
||||
const providerUser = await providerInstance.getUser(body.providerToken);
|
||||
|
|
@ -118,15 +132,19 @@ export class AuthService {
|
|||
return user;
|
||||
}
|
||||
|
||||
const create = await this._organizationService.createOrgAndUser({
|
||||
company: body.company,
|
||||
email: providerUser.email,
|
||||
password: '',
|
||||
provider,
|
||||
providerId: providerUser.id,
|
||||
});
|
||||
const create = await this._organizationService.createOrgAndUser(
|
||||
{
|
||||
company: body.company,
|
||||
email: providerUser.email,
|
||||
password: '',
|
||||
provider,
|
||||
providerId: providerUser.id,
|
||||
},
|
||||
ip,
|
||||
userAgent
|
||||
);
|
||||
|
||||
NewsletterService.register(providerUser.email);
|
||||
await NewsletterService.register(providerUser.email);
|
||||
|
||||
return create.users[0].user;
|
||||
}
|
||||
|
|
@ -162,7 +180,11 @@ export class AuthService {
|
|||
}
|
||||
|
||||
async activate(code: string) {
|
||||
const user = AuthChecker.verifyJWT(code) as { id: string, activated: boolean, email: string };
|
||||
const user = AuthChecker.verifyJWT(code) as {
|
||||
id: string;
|
||||
activated: boolean;
|
||||
email: string;
|
||||
};
|
||||
if (user.id && !user.activated) {
|
||||
const getUserAgain = await this._userService.getUserByEmail(user.email);
|
||||
if (getUserAgain.activated) {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,5 +1,6 @@
|
|||
import { ReactNode } from 'react';
|
||||
import { PreviewWrapper } from '@gitroom/frontend/components/preview/preview.wrapper';
|
||||
|
||||
export default async function AppLayout({ children }: { children: ReactNode }) {
|
||||
return children;
|
||||
}
|
||||
return <PreviewWrapper>{children}</PreviewWrapper>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,13 @@ export const dynamic = 'force-dynamic';
|
|||
import { Metadata } from 'next';
|
||||
import { isGeneralServerSide } from '@gitroom/helpers/utils/is.general.server.side';
|
||||
import Image from 'next/image';
|
||||
import clsx from 'clsx';
|
||||
import Link from 'next/link';
|
||||
import { Button } from '@gitroom/react/form/button';
|
||||
import { CommentsComponents } from '@gitroom/frontend/components/preview/comments.components';
|
||||
import dayjs from 'dayjs';
|
||||
import utc from 'dayjs/plugin/utc';
|
||||
|
||||
dayjs.extend(utc);
|
||||
export const metadata: Metadata = {
|
||||
title: `${isGeneralServerSide() ? 'Postiz' : 'Gitroom'} Preview`,
|
||||
description: '',
|
||||
|
|
@ -16,13 +19,10 @@ export const metadata: Metadata = {
|
|||
|
||||
export default async function Auth({
|
||||
params: { id },
|
||||
searchParams,
|
||||
}: {
|
||||
params: { id: string };
|
||||
searchParams: any;
|
||||
}) {
|
||||
const post = await (await internalFetch(`/public/posts/${id}`)).json();
|
||||
console.log(JSON.stringify(post, null, 2));
|
||||
return (
|
||||
<div>
|
||||
<div className="mx-auto w-full max-w-[1346px] py-3 text-white">
|
||||
|
|
@ -73,16 +73,16 @@ export default async function Auth({
|
|||
</div>
|
||||
</div>
|
||||
<div className="text-sm text-gray-400">
|
||||
Publication Date: December 14, 2024
|
||||
Publication Date: {dayjs.utc(post[0].createdAt).local().format('MMMM D, YYYY h:mm A')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col lg:flex-row text-white w-full max-w-[1346px] mx-auto">
|
||||
<div className="flex-1 bg-third border border-tableBorder">
|
||||
<div>
|
||||
<div className="flex-1">
|
||||
<div className="gap-[20px] flex flex-col">
|
||||
{post.map((p: any, index: number) => (
|
||||
<div key={String(p.id)} className="relative px-4 py-4">
|
||||
<div key={String(p.id)} className="relative px-4 py-4 bg-third border border-tableBorder">
|
||||
<div className="flex space-x-3">
|
||||
<div>
|
||||
<span className="flex shrink-0 overflow-hidden rounded-full h-30 w-30">
|
||||
|
|
@ -92,9 +92,6 @@ export default async function Auth({
|
|||
src={post[0].integration.picture}
|
||||
/>
|
||||
</span>
|
||||
{post.length - 1 !== index && (
|
||||
<div className="absolute left-10 top-5 h-full w-0.5 -translate-x-1/2 bg-tableBorder" />
|
||||
)}
|
||||
</div>
|
||||
<div className="flex-1 space-y-1">
|
||||
<div className="flex items-center space-x-2">
|
||||
|
|
@ -172,73 +169,9 @@ export default async function Auth({
|
|||
</div>
|
||||
</div>
|
||||
<div className="w-full lg:w-96 lg:flex-shrink-0">
|
||||
<div className="border-l border-tableBorder p-4">
|
||||
<div className="p-4">
|
||||
<h2 className="mb-4 text-xl font-bold">Add a comment</h2>
|
||||
<div className="mb-6 flex space-x-3">
|
||||
<div className="flex-1 space-y-2">
|
||||
<textarea
|
||||
className="flex w-full rounded-md border border-input px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 min-h-[80px] resize-none bg-transparent text-white placeholder-gray-500 focus:ring-0"
|
||||
placeholder="What's happening?"
|
||||
defaultValue={''}
|
||||
/>
|
||||
<div className="flex justify-end">
|
||||
<Button>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={24}
|
||||
height={24}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth={2}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="lucide lucide-send mr-2 h-4 w-4"
|
||||
>
|
||||
<path d="m22 2-7 20-4-9-9-4Z" />
|
||||
<path d="M22 2 11 13" />
|
||||
</svg>
|
||||
Post
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-lg font-semibold">Comments</h3>
|
||||
<div className="flex space-x-3 border-t border-tableBorder py-3">
|
||||
<div className="flex-1 space-y-1">
|
||||
<div className="flex items-center space-x-2">
|
||||
<h3 className="text-sm font-semibold">Alice Smith</h3>
|
||||
<span className="text-xs text-gray-500">· 1h</span>
|
||||
</div>
|
||||
<p className="text-sm text-gray-300">
|
||||
Looks great! Congrats on the launch!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex space-x-3 border-t border-tableBorder py-3">
|
||||
<div className="flex-1 space-y-1">
|
||||
<div className="flex items-center space-x-2">
|
||||
<h3 className="text-sm font-semibold">Bob Johnson</h3>
|
||||
<span className="text-xs text-gray-500">· 30m</span>
|
||||
</div>
|
||||
<p className="text-sm text-gray-300">
|
||||
Nice work! The design is really sleek.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex space-x-3 border-t border-tableBorder py-3">
|
||||
<div className="flex-1 space-y-1">
|
||||
<div className="flex items-center space-x-2">
|
||||
<h3 className="text-sm font-semibold">Charlie Brown</h3>
|
||||
<span className="text-xs text-gray-500">· 4h</span>
|
||||
</div>
|
||||
<p className="text-sm text-gray-300">
|
||||
Can{"'"}t wait to hear your talk!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<CommentsComponents />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import { Fragment } from 'react';
|
|||
import { PHProvider } from '@gitroom/react/helpers/posthog';
|
||||
import UtmSaver from '@gitroom/helpers/utils/utm.saver';
|
||||
import { ToltScript } from '@gitroom/frontend/components/layout/tolt.script';
|
||||
import { FacebookComponent } from '@gitroom/frontend/components/layout/facebook.component';
|
||||
|
||||
const chakra = Chakra_Petch({ weight: '400', subsets: ['latin'] });
|
||||
|
||||
|
|
@ -25,11 +26,7 @@ export default async function AppLayout({ children }: { children: ReactNode }) {
|
|||
return (
|
||||
<html className={interClass}>
|
||||
<head>
|
||||
<link
|
||||
rel="icon"
|
||||
href="/favicon.ico"
|
||||
sizes="any"
|
||||
/>
|
||||
<link rel="icon" href="/favicon.ico" sizes="any" />
|
||||
</head>
|
||||
<body className={clsx(chakra.className, 'text-primary dark')}>
|
||||
<VariableContextComponent
|
||||
|
|
@ -44,8 +41,10 @@ export default async function AppLayout({ children }: { children: ReactNode }) {
|
|||
isGeneral={!!process.env.IS_GENERAL}
|
||||
uploadDirectory={process.env.NEXT_PUBLIC_UPLOAD_STATIC_DIRECTORY!}
|
||||
tolt={process.env.NEXT_PUBLIC_TOLT!}
|
||||
facebookPixel={process.env.NEXT_PUBLIC_FACEBOOK_PIXEL!}
|
||||
>
|
||||
<ToltScript />
|
||||
<FacebookComponent />
|
||||
<Plausible
|
||||
domain={!!process.env.IS_GENERAL ? 'postiz.com' : 'gitroom.com'}
|
||||
>
|
||||
|
|
@ -53,8 +52,10 @@ export default async function AppLayout({ children }: { children: ReactNode }) {
|
|||
phkey={process.env.NEXT_PUBLIC_POSTHOG_KEY}
|
||||
host={process.env.NEXT_PUBLIC_POSTHOG_HOST}
|
||||
>
|
||||
<UtmSaver />
|
||||
<LayoutContext>{children}</LayoutContext>
|
||||
<LayoutContext>
|
||||
<UtmSaver />
|
||||
{children}
|
||||
</LayoutContext>
|
||||
</PHProvider>
|
||||
</Plausible>
|
||||
</VariableContextComponent>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import { useForm, SubmitHandler, FormProvider } from 'react-hook-form';
|
||||
import { FormProvider, SubmitHandler, useForm } from 'react-hook-form';
|
||||
import { useFetch } from '@gitroom/helpers/utils/custom.fetch';
|
||||
import Link from 'next/link';
|
||||
import { Button } from '@gitroom/react/form/button';
|
||||
|
|
@ -16,6 +16,8 @@ import clsx from 'clsx';
|
|||
import { GoogleProvider } from '@gitroom/frontend/components/auth/providers/google.provider';
|
||||
import { useFireEvents } from '@gitroom/helpers/utils/use.fire.events';
|
||||
import { useVariables } from '@gitroom/react/helpers/variable.context';
|
||||
import { useTrack } from '@gitroom/react/helpers/use.track';
|
||||
import { TrackEnum } from '@gitroom/nestjs-libraries/user/track.enum';
|
||||
|
||||
type Inputs = {
|
||||
email: string;
|
||||
|
|
@ -83,10 +85,11 @@ export function RegisterAfter({
|
|||
token: string;
|
||||
provider: string;
|
||||
}) {
|
||||
const {isGeneral} = useVariables();
|
||||
const { isGeneral } = useVariables();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const router = useRouter();
|
||||
const fireEvents = useFireEvents();
|
||||
const track = useTrack();
|
||||
|
||||
const isAfterProvider = useMemo(() => {
|
||||
return !!token && !!provider;
|
||||
|
|
@ -112,27 +115,33 @@ export function RegisterAfter({
|
|||
await fetchData('/auth/register', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ ...data }),
|
||||
}).then((response) => {
|
||||
setLoading(false);
|
||||
|
||||
if (response.status === 200) {
|
||||
fireEvents('register')
|
||||
|
||||
if (response.headers.get('activate') === "true") {
|
||||
router.push('/auth/activate');
|
||||
} else {
|
||||
router.push('/auth/login');
|
||||
}
|
||||
} else {
|
||||
form.setError('email', {
|
||||
message: getHelpfulReasonForRegistrationFailure(response.status),
|
||||
});
|
||||
}
|
||||
}).catch(e => {
|
||||
form.setError("email", {
|
||||
message: 'General error: ' + e.toString() + '. Please check your browser console.',
|
||||
});
|
||||
})
|
||||
.then((response) => {
|
||||
setLoading(false);
|
||||
|
||||
if (response.status === 200) {
|
||||
fireEvents('register');
|
||||
return track(TrackEnum.CompleteRegistration).then(() => {
|
||||
if (response.headers.get('activate') === 'true') {
|
||||
router.push('/auth/activate');
|
||||
} else {
|
||||
router.push('/auth/login');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.setError('email', {
|
||||
message: getHelpfulReasonForRegistrationFailure(response.status),
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
form.setError('email', {
|
||||
message:
|
||||
'General error: ' +
|
||||
e.toString() +
|
||||
'. Please check your browser console.',
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
@ -143,7 +152,8 @@ export function RegisterAfter({
|
|||
Sign Up
|
||||
</h1>
|
||||
</div>
|
||||
{!isAfterProvider && (!isGeneral ? <GithubProvider /> : <GoogleProvider />)}
|
||||
{!isAfterProvider &&
|
||||
(!isGeneral ? <GithubProvider /> : <GoogleProvider />)}
|
||||
{!isAfterProvider && (
|
||||
<div className="h-[20px] mb-[24px] mt-[24px] relative">
|
||||
<div className="absolute w-full h-[1px] bg-fifth top-[50%] -translate-y-[50%]" />
|
||||
|
|
@ -198,7 +208,11 @@ export function RegisterAfter({
|
|||
</div>
|
||||
<div className="text-center mt-6">
|
||||
<div className="w-full flex">
|
||||
<Button type="submit" className="flex-1 rounded-[4px]" loading={loading}>
|
||||
<Button
|
||||
type="submit"
|
||||
className="flex-1 rounded-[4px]"
|
||||
loading={loading}
|
||||
>
|
||||
Create Account
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -5,19 +5,9 @@ import useSWR from 'swr';
|
|||
import { LoadingComponent } from '@gitroom/frontend/components/layout/loading';
|
||||
import { useFetch } from '@gitroom/helpers/utils/custom.fetch';
|
||||
import { MainBillingComponent } from './main.billing.component';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import { useFireEvents } from '@gitroom/helpers/utils/use.fire.events';
|
||||
|
||||
export const BillingComponent = () => {
|
||||
const fetch = useFetch();
|
||||
const searchParams = useSearchParams();
|
||||
const fireEvents = useFireEvents();
|
||||
|
||||
useEffect(() => {
|
||||
if (searchParams.get('check')) {
|
||||
fireEvents('purchase');
|
||||
}
|
||||
}, []);
|
||||
|
||||
const load = useCallback(async (path: string) => {
|
||||
return await (await fetch(path)).json();
|
||||
|
|
@ -36,7 +26,5 @@ export const BillingComponent = () => {
|
|||
return <LoadingComponent />;
|
||||
}
|
||||
|
||||
return (
|
||||
<MainBillingComponent sub={subscription?.subscription} />
|
||||
);
|
||||
return <MainBillingComponent sub={subscription?.subscription} />;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,13 +4,28 @@ import { FC, useCallback, useState } from 'react';
|
|||
import clsx from 'clsx';
|
||||
import interClass from '@gitroom/react/helpers/inter.font';
|
||||
import { useVariables } from '@gitroom/react/helpers/variable.context';
|
||||
import { useUser } from '@gitroom/frontend/components/layout/user.context';
|
||||
|
||||
const useFaqList = () => {
|
||||
const {isGeneral} = useVariables();
|
||||
const { isGeneral } = useVariables();
|
||||
const user = useUser();
|
||||
return [
|
||||
...(user?.allowTrial
|
||||
? [
|
||||
{
|
||||
title: 'Am I going to be charged by Postiz?',
|
||||
description:
|
||||
'To confirm credit card information Postiz will hold $2 and release it immediately',
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
title: `Can I trust ${isGeneral ? 'Postiz' : 'Gitroom'}?`,
|
||||
description: `${isGeneral ? 'Postiz' : 'Gitroom'} is proudly open-source! We believe in an ethical and transparent culture, meaning that ${isGeneral ? 'Postiz' : 'Gitroom'} will live forever. You can check out the entire code or use it for personal projects. To view the open-source repository, <a href="https://github.com/gitroomhq/postiz-app" target="_blank" style="text-decoration: underline;">click here</a>.`,
|
||||
description: `${
|
||||
isGeneral ? 'Postiz' : 'Gitroom'
|
||||
} is proudly open-source! We believe in an ethical and transparent culture, meaning that ${
|
||||
isGeneral ? 'Postiz' : 'Gitroom'
|
||||
} will live forever. You can check out the entire code or use it for personal projects. To view the open-source repository, <a href="https://github.com/gitroomhq/postiz-app" target="_blank" style="text-decoration: underline;">click here</a>.`,
|
||||
},
|
||||
{
|
||||
title: 'What are channels?',
|
||||
|
|
@ -29,7 +44,7 @@ For example, you can schedule your posts on X, Facebook, Instagram, TikTok, YouT
|
|||
description: `We automate ChatGPT to help you write your social posts and articles`,
|
||||
},
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
export const FAQSection: FC<{ title: string; description: string }> = (
|
||||
props
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ import { Textarea } from '@gitroom/react/form/textarea';
|
|||
import { useFireEvents } from '@gitroom/helpers/utils/use.fire.events';
|
||||
import { useUtmUrl } from '@gitroom/helpers/utils/utm.saver';
|
||||
import { useTolt } from '@gitroom/frontend/components/layout/tolt.script';
|
||||
import { useTrack } from '@gitroom/react/helpers/use.track';
|
||||
import { TrackEnum } from '@gitroom/nestjs-libraries/user/track.enum';
|
||||
|
||||
export interface Tiers {
|
||||
month: Array<{
|
||||
|
|
@ -223,6 +225,7 @@ export const MainBillingComponent: FC<{
|
|||
const router = useRouter();
|
||||
const utm = useUtmUrl();
|
||||
const tolt = useTolt();
|
||||
const track = useTrack();
|
||||
|
||||
const [subscription, setSubscription] = useState<Subscription | undefined>(
|
||||
sub
|
||||
|
|
@ -350,12 +353,18 @@ export const MainBillingComponent: FC<{
|
|||
period: monthlyOrYearly === 'on' ? 'YEARLY' : 'MONTHLY',
|
||||
utm,
|
||||
billing,
|
||||
tolt: tolt()
|
||||
tolt: tolt(),
|
||||
}),
|
||||
})
|
||||
).json();
|
||||
|
||||
if (url) {
|
||||
await track(TrackEnum.InitiateCheckout, {
|
||||
value:
|
||||
pricing[billing][
|
||||
monthlyOrYearly === 'on' ? 'year_price' : 'month_price'
|
||||
],
|
||||
});
|
||||
window.location.href = url;
|
||||
return;
|
||||
}
|
||||
|
|
@ -412,13 +421,13 @@ export const MainBillingComponent: FC<{
|
|||
<div>YEARLY</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-[16px]">
|
||||
<div className="flex gap-[16px] [@media(max-width:1024px)]:flex-col [@media(max-width:1024px)]:text-center">
|
||||
{Object.entries(pricing)
|
||||
.filter((f) => !isGeneral || f[0] !== 'FREE')
|
||||
.map(([name, values]) => (
|
||||
<div
|
||||
key={name}
|
||||
className="flex-1 bg-sixth border border-customColor6 rounded-[4px] p-[24px] gap-[16px] flex flex-col"
|
||||
className="flex-1 bg-sixth border border-customColor6 rounded-[4px] p-[24px] gap-[16px] flex flex-col [@media(max-width:1024px)]:items-center"
|
||||
>
|
||||
<div className="text-[18px]">{name}</div>
|
||||
<div className="text-[38px] flex gap-[2px] items-center">
|
||||
|
|
@ -472,7 +481,7 @@ export const MainBillingComponent: FC<{
|
|||
.format('D MMM, YYYY')}`
|
||||
: 'Cancel subscription'
|
||||
: // @ts-ignore
|
||||
user?.tier === 'FREE' || user?.tier?.current === 'FREE'
|
||||
(user?.tier === 'FREE' || user?.tier?.current === 'FREE') && user.allowTrial
|
||||
? 'Start 7 days free trial'
|
||||
: 'Purchase'}
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import Loading from 'react-loading';
|
||||
import { useFetch } from '@gitroom/helpers/utils/custom.fetch';
|
||||
import { timer } from '@gitroom/helpers/utils/timer';
|
||||
import { useToaster } from '@gitroom/react/toaster/toaster';
|
||||
|
||||
export const CheckPayment: FC<{ check: string; mutate: () => void }> = (props) => {
|
||||
const [showLoader, setShowLoader] = useState(true);
|
||||
const fetch = useFetch();
|
||||
const toaster = useToaster();
|
||||
|
||||
const checkSubscription = useCallback(async () => {
|
||||
const {status} = await (await fetch('/billing/check/' + props.check)).json();
|
||||
if (status === 0) {
|
||||
await timer(1000);
|
||||
return checkSubscription();
|
||||
}
|
||||
|
||||
if (status === 1) {
|
||||
toaster.show(
|
||||
'We could not validate your payment method, please try again',
|
||||
'warning'
|
||||
);
|
||||
setShowLoader(false);
|
||||
}
|
||||
|
||||
if (status === 2) {
|
||||
setShowLoader(false);
|
||||
props.mutate();
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
checkSubscription();
|
||||
}, []);
|
||||
|
||||
if (showLoader) {
|
||||
return (
|
||||
<div className="fixed bg-black/40 w-full h-full flex justify-center items-center z-[400]">
|
||||
<div>
|
||||
<Loading type="spin" color="#612AD5" height={250} width={250} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
'use client';
|
||||
|
||||
import Script from "next/script";
|
||||
|
||||
export const FacebookComponent = () => {
|
||||
if (!process.env.NEXT_PUBLIC_FACEBOOK_PIXEL) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Script strategy="afterInteractive" id="fb-pixel">
|
||||
{`!function(f,b,e,v,n,t,s)
|
||||
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
|
||||
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
|
||||
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
|
||||
n.queue=[];t=b.createElement(e);t.async=!0;
|
||||
t.src=v;s=b.getElementsByTagName(e)[0];
|
||||
s.parentNode.insertBefore(t,s)}(window, document,'script',
|
||||
'/f.js');
|
||||
fbq('init', '${process.env.NEXT_PUBLIC_FACEBOOK_PIXEL}');
|
||||
`}
|
||||
</Script>
|
||||
);
|
||||
};
|
||||
|
|
@ -20,6 +20,10 @@ function LayoutContextInner(params: { children: ReactNode }) {
|
|||
|
||||
const afterRequest = useCallback(
|
||||
async (url: string, options: RequestInit, response: Response) => {
|
||||
if (typeof window !== 'undefined' && window.location.href.includes('/p/')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const reloadOrOnboarding =
|
||||
response?.headers?.get('reload') ||
|
||||
response?.headers?.get('onboarding');
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import { ReactNode, useCallback } from 'react';
|
||||
import { ReactNode, useCallback, useEffect } from 'react';
|
||||
import { Title } from '@gitroom/frontend/components/layout/title';
|
||||
import { ContextWrapper } from '@gitroom/frontend/components/layout/user.context';
|
||||
import { TopMenu } from '@gitroom/frontend/components/layout/top.menu';
|
||||
|
|
@ -8,7 +8,7 @@ import { MantineWrapper } from '@gitroom/react/helpers/mantine.wrapper';
|
|||
import { ToolTip } from '@gitroom/frontend/components/layout/top.tip';
|
||||
import { ShowMediaBoxModal } from '@gitroom/frontend/components/media/media.component';
|
||||
import Image from 'next/image';
|
||||
import { Toaster } from '@gitroom/react/toaster/toaster';
|
||||
import { Toaster, useToaster } from '@gitroom/react/toaster/toaster';
|
||||
import { ShowPostSelector } from '@gitroom/frontend/components/post-url-selector/post.url.selector';
|
||||
import { OrganizationSelector } from '@gitroom/frontend/components/layout/organization.selector';
|
||||
import NotificationComponent from '@gitroom/frontend/components/notifications/notification.component';
|
||||
|
|
@ -37,6 +37,8 @@ const ModeComponent = dynamic(
|
|||
);
|
||||
|
||||
import { extend } from 'dayjs';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import { CheckPayment } from '@gitroom/frontend/components/layout/check.payment';
|
||||
|
||||
extend(utc);
|
||||
extend(weekOfYear);
|
||||
|
|
@ -47,11 +49,12 @@ export const LayoutSettings = ({ children }: { children: ReactNode }) => {
|
|||
const fetch = useFetch();
|
||||
const { isGeneral } = useVariables();
|
||||
const { backendUrl, billingEnabled } = useVariables();
|
||||
const searchParams = useSearchParams();
|
||||
const load = useCallback(async (path: string) => {
|
||||
return await (await fetch(path)).json();
|
||||
}, []);
|
||||
|
||||
const { data: user } = useSWR('/user/self', load, {
|
||||
const { data: user, mutate } = useSWR('/user/self', load, {
|
||||
revalidateOnFocus: false,
|
||||
revalidateOnReconnect: false,
|
||||
revalidateIfStale: false,
|
||||
|
|
@ -67,89 +70,95 @@ export const LayoutSettings = ({ children }: { children: ReactNode }) => {
|
|||
credentials="include"
|
||||
runtimeUrl={backendUrl + '/copilot/chat'}
|
||||
>
|
||||
<ContextWrapper user={user}>
|
||||
<MantineWrapper>
|
||||
<ToolTip />
|
||||
<ShowMediaBoxModal />
|
||||
<ShowLinkedinCompany />
|
||||
<Toaster />
|
||||
<ShowPostSelector />
|
||||
<NewSubscription />
|
||||
{user.tier !== 'FREE' && <Onboarding />}
|
||||
<Support />
|
||||
<ContinueProvider />
|
||||
<div className="min-h-[100vh] w-full max-w-[1440px] mx-auto bg-primary sm:px-6 px-0 text-textColor flex flex-col">
|
||||
{user?.admin && <Impersonate />}
|
||||
<nav className="px-0 md:px-[23px] gap-2 grid grid-rows-[repeat(2,_auto)] grid-cols-2 md:grid-rows-1 md:grid-cols-[repeat(3,_auto)] items-center justify-between z-[200] sticky top-0 bg-primary">
|
||||
<Link
|
||||
href="/"
|
||||
className="text-2xl flex items-center gap-[10px] text-textColor order-1"
|
||||
>
|
||||
<div className="min-w-[55px]">
|
||||
<Image
|
||||
src={isGeneral ? '/postiz.svg' : '/logo.svg'}
|
||||
width={55}
|
||||
height={53}
|
||||
alt="Logo"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(!isGeneral ? 'mt-[12px]' : 'min-w-[80px]')}
|
||||
>
|
||||
{isGeneral ? (
|
||||
<svg
|
||||
width="80"
|
||||
height="75"
|
||||
viewBox="0 0 366 167"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M24.9659 30.4263V43.3825C26.9237 41.3095 29.3998 39.582 32.3941 38.2C35.3885 36.7028 39.0162 35.9543 43.2774 35.9543C47.1931 35.9543 50.8784 36.7028 54.3334 38.2C57.9036 39.6972 61.0131 42.1157 63.6619 45.4555C66.4259 48.6802 68.6141 52.9989 70.2264 58.4118C71.8387 63.8246 72.6449 70.3891 72.6449 78.1053C72.6449 83.6333 72.1266 89.1613 71.0902 94.6893C70.1688 100.217 68.4989 105.169 66.0804 109.546C63.6619 113.922 60.3796 117.492 56.2336 120.256C52.2028 122.905 47.1355 124.23 41.0316 124.23C36.6553 124.23 33.2003 123.654 30.6666 122.502C28.1329 121.235 26.2327 119.796 24.9659 118.183V160.162L0.0898438 166.381V30.4263H24.9659ZM32.7396 109.2C35.734 109.2 38.2676 108.221 40.3406 106.264C42.4136 104.191 44.026 101.542 45.1776 98.3171C46.4445 95.0924 47.3082 91.5222 47.7689 87.6066C48.3447 83.5757 48.6326 79.6025 48.6326 75.6868C48.6326 69.3526 48.0568 64.3429 46.9051 60.6575C45.8686 56.9722 44.6018 54.2658 43.1046 52.5383C41.6075 50.6956 40.1103 49.5439 38.6131 49.0833C37.2311 48.6226 36.137 48.3923 35.3309 48.3923C33.2579 48.3923 31.2425 49.1409 29.2846 50.638C27.3268 52.02 25.8872 54.1506 24.9659 57.0298V105.227C25.5417 106.148 26.463 107.07 27.7299 107.991C28.9967 108.797 30.6666 109.2 32.7396 109.2Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M188.176 31.4627C191.055 42.5188 193.588 51.5593 195.777 58.5845C197.965 65.4945 199.807 71.3105 201.305 76.0323C202.917 80.7541 204.126 84.9001 204.932 88.4703C205.854 92.0405 206.314 96.0137 206.314 100.39C208.272 99.1232 210.172 97.7988 212.015 96.4168C213.858 94.9196 215.413 93.5376 216.679 92.2708H223.935C220.825 96.9926 217.543 100.908 214.088 104.018C210.633 107.012 207.293 109.661 204.069 111.964C201.996 116.456 198.829 119.623 194.567 121.466C190.306 123.308 185.872 124.23 181.266 124.23C176.083 124.23 171.649 123.539 167.964 122.157C164.279 120.659 161.227 118.702 158.808 116.283C156.505 113.749 154.777 110.87 153.626 107.646C152.474 104.421 151.898 101.023 151.898 97.4533C151.898 93.5376 152.819 90.4857 154.662 88.2975C156.62 85.9942 158.866 84.8426 161.399 84.8426C168.424 84.8426 171.937 87.6641 171.937 93.3073C171.937 95.15 171.304 96.7047 170.037 97.9716C168.77 99.2384 167.158 99.8718 165.2 99.8718C164.278 99.8718 163.3 99.7566 162.263 99.5263C161.342 99.1808 160.593 98.5474 160.017 97.6261C160.939 101.657 162.436 104.824 164.509 107.127C166.697 109.431 169.461 110.582 172.801 110.582C175.68 110.582 177.811 109.891 179.193 108.509C180.575 107.012 181.266 104.478 181.266 100.908C181.266 97.1078 180.92 93.7104 180.229 90.7161C179.653 87.6066 178.732 84.2091 177.465 80.5238C176.198 76.8385 174.644 72.4621 172.801 67.3948C170.958 62.2123 168.885 55.5326 166.582 47.3558C160.823 59.6786 153.222 67.5675 143.779 71.0225C143.779 71.9439 143.779 72.8652 143.779 73.7865C143.894 74.5927 143.952 75.4565 143.952 76.3778C143.952 83.0575 143.376 89.334 142.224 95.2076C141.072 100.966 139.115 106.033 136.351 110.41C133.702 114.671 130.247 118.068 125.986 120.602C121.724 123.02 116.484 124.23 110.265 124.23C106.004 124.23 101.916 123.596 98 122.329C94.1995 120.947 90.8021 118.759 87.8078 115.765C84.8134 112.655 82.3949 108.624 80.5523 103.672C78.8248 98.605 77.961 92.4436 77.961 85.188C77.961 80.2359 78.4793 74.9382 79.5158 69.295C80.5523 63.5367 82.4525 58.1814 85.2165 53.2293C87.9805 48.2771 91.7234 44.1887 96.4453 40.964C101.282 37.6242 107.444 35.9543 114.93 35.9543C122.646 35.9543 128.807 38.0273 133.414 42.1733C138.136 46.3193 141.303 52.9989 142.915 62.2123C146.946 61.2909 150.574 58.5269 153.798 53.9203C157.138 49.1984 160.305 42.8643 163.3 34.9177L188.176 31.4627ZM115.102 107.991C117.521 107.991 119.594 107.185 121.321 105.573C123.164 103.845 124.661 101.542 125.813 98.6626C126.964 95.6682 127.771 92.1556 128.231 88.1248C128.807 84.094 129.095 79.7176 129.095 74.9958V72.75C124.488 71.7135 122.185 68.3161 122.185 62.5578C122.185 58.8724 123.682 56.4539 126.677 55.3023C125.41 51.6169 123.855 49.1984 122.012 48.0468C120.285 46.8951 118.788 46.3193 117.521 46.3193C114.987 46.3193 112.799 47.5285 110.956 49.947C109.229 52.2504 107.789 55.2447 106.638 58.93C105.486 62.5002 104.622 66.4734 104.046 70.8498C103.586 75.2261 103.355 79.4297 103.355 83.4605C103.355 88.6431 103.701 92.8466 104.392 96.0713C105.198 99.296 106.177 101.772 107.329 103.5C108.48 105.227 109.747 106.436 111.129 107.127C112.511 107.703 113.835 107.991 115.102 107.991Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M239.554 9.52348V36.818H250.092V43.728H239.554V95.5531C239.554 100.39 240.187 103.615 241.454 105.227C242.836 106.724 245.197 107.473 248.537 107.473C251.877 107.473 254.641 106.033 256.829 103.154C259.132 100.275 260.457 96.6471 260.802 92.2708H268.058C267.136 99.296 265.524 104.939 263.221 109.2C260.917 113.346 258.326 116.571 255.447 118.874C252.568 121.062 249.631 122.502 246.637 123.193C243.642 123.884 240.993 124.23 238.69 124.23C229.822 124.23 223.603 121.811 220.033 116.974C216.463 112.022 214.678 105.515 214.678 97.4533V43.728H209.15V36.818H214.678V12.9785L239.554 9.52348Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M258.833 13.8422C258.833 10.0417 260.158 6.81706 262.806 4.16823C265.455 1.40422 268.68 0.0222168 272.48 0.0222168C276.281 0.0222168 279.506 1.40422 282.154 4.16823C284.918 6.81706 286.3 10.0417 286.3 13.8422C286.3 17.6427 284.918 20.8674 282.154 23.5162C279.506 26.1651 276.281 27.4895 272.48 27.4895C268.68 27.4895 265.455 26.1651 262.806 23.5162C260.158 20.8674 258.833 17.6427 258.833 13.8422ZM285.609 36.818V95.5531C285.609 100.39 286.243 103.615 287.51 105.227C288.892 106.724 291.253 107.473 294.592 107.473C296.09 107.473 297.184 107.358 297.875 107.127C298.681 106.897 299.372 106.667 299.948 106.436C300.063 107.012 300.12 107.588 300.12 108.164C300.12 108.74 300.12 109.315 300.12 109.891C300.12 112.77 299.602 115.131 298.566 116.974C297.644 118.817 296.377 120.314 294.765 121.466C293.268 122.502 291.598 123.193 289.755 123.539C288.028 123.999 286.358 124.23 284.746 124.23C275.878 124.23 269.659 121.811 266.089 116.974C262.518 112.022 260.733 105.515 260.733 97.4533V36.818H285.609ZM351.773 107.473C350.391 107.358 349.354 106.897 348.663 106.091C347.972 105.169 347.627 104.133 347.627 102.981C347.627 101.484 348.26 100.045 349.527 98.6626C350.794 97.1654 352.867 96.4168 355.746 96.4168C358.971 96.4168 361.389 97.5109 363.001 99.6991C364.614 101.772 365.42 104.248 365.42 107.127C365.42 108.97 365.074 110.87 364.383 112.828C363.692 114.671 362.598 116.398 361.101 118.011C359.604 119.508 357.761 120.775 355.573 121.811C353.385 122.732 350.851 123.193 347.972 123.193H300.293L334.152 46.1465H321.369C318.835 46.1465 316.704 46.3193 314.977 46.6648C313.365 46.8951 312.558 47.5285 312.558 48.565C312.558 49.0257 312.674 49.256 312.904 49.256C313.249 49.256 313.595 49.3712 313.94 49.6015C314.401 49.8318 314.747 50.2925 314.977 50.9835C315.322 51.6745 315.495 52.8838 315.495 54.6113C315.495 57.1449 314.689 58.9876 313.077 60.1393C311.579 61.2909 309.852 61.8668 307.894 61.8668C305.591 61.8668 303.345 61.1182 301.157 59.621C299.084 58.0087 298.047 55.5902 298.047 52.3655C298.047 50.638 298.393 48.9105 299.084 47.183C299.775 45.3403 300.811 43.6704 302.193 42.1733C303.575 40.5609 305.303 39.2941 307.376 38.3728C309.449 37.3363 311.867 36.818 314.631 36.818H362.138L329.142 109.891C329.833 109.891 330.812 109.949 332.079 110.064C333.346 110.179 334.67 110.294 336.052 110.41C337.55 110.525 338.989 110.64 340.371 110.755C341.868 110.87 343.193 110.928 344.344 110.928C346.417 110.928 348.145 110.697 349.527 110.237C351.024 109.776 351.773 108.855 351.773 107.473Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
) : (
|
||||
'Gitroom'
|
||||
)}
|
||||
</div>
|
||||
</Link>
|
||||
{user?.orgId &&
|
||||
(user.tier !== 'FREE' || !isGeneral || !billingEnabled) ? (
|
||||
<TopMenu />
|
||||
) : (
|
||||
<div />
|
||||
)}
|
||||
<div id = "systray-buttons" className="flex items-center justify-self-end gap-[8px] order-2 md:order-3">
|
||||
<ModeComponent />
|
||||
<SettingsComponent />
|
||||
<NotificationComponent />
|
||||
<OrganizationSelector />
|
||||
<MantineWrapper>
|
||||
{user.tier === 'FREE' && searchParams.get('check') && (
|
||||
<CheckPayment check={searchParams.get('check')!} mutate={mutate} />
|
||||
)}
|
||||
<ToolTip />
|
||||
<ShowMediaBoxModal />
|
||||
<ShowLinkedinCompany />
|
||||
<Toaster />
|
||||
<ShowPostSelector />
|
||||
<NewSubscription />
|
||||
{user.tier !== 'FREE' && <Onboarding />}
|
||||
<Support />
|
||||
<ContinueProvider />
|
||||
<div className="min-h-[100vh] w-full max-w-[1440px] mx-auto bg-primary px-6 text-textColor flex flex-col">
|
||||
{user?.admin && <Impersonate />}
|
||||
<nav className="flex items-center justify-between">
|
||||
<Link
|
||||
href="/"
|
||||
className="text-2xl flex items-center gap-[10px] text-textColor order-1"
|
||||
>
|
||||
<div className="min-w-[55px]">
|
||||
<Image
|
||||
src={isGeneral ? '/postiz.svg' : '/logo.svg'}
|
||||
width={55}
|
||||
height={53}
|
||||
alt="Logo"
|
||||
/>
|
||||
</div>
|
||||
</nav>
|
||||
<div className="flex-1 flex">
|
||||
<div className="flex-1 rounded-3xl px-0 md:px-[23px] py-[17px] flex flex-col">
|
||||
{user.tier === 'FREE' && isGeneral && billingEnabled ? (
|
||||
<>
|
||||
<div className="text-center mb-[20px] text-xl">
|
||||
<h1 className="text-3xl">
|
||||
Join 1000+ Entrepreneurs Who Use Postiz
|
||||
<br />
|
||||
To Manage All Your Social Media Channels
|
||||
</h1>
|
||||
<div
|
||||
className={clsx(!isGeneral ? 'mt-[12px]' : 'min-w-[80px]')}
|
||||
>
|
||||
{isGeneral ? (
|
||||
<svg
|
||||
width="80"
|
||||
height="75"
|
||||
viewBox="0 0 366 167"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M24.9659 30.4263V43.3825C26.9237 41.3095 29.3998 39.582 32.3941 38.2C35.3885 36.7028 39.0162 35.9543 43.2774 35.9543C47.1931 35.9543 50.8784 36.7028 54.3334 38.2C57.9036 39.6972 61.0131 42.1157 63.6619 45.4555C66.4259 48.6802 68.6141 52.9989 70.2264 58.4118C71.8387 63.8246 72.6449 70.3891 72.6449 78.1053C72.6449 83.6333 72.1266 89.1613 71.0902 94.6893C70.1688 100.217 68.4989 105.169 66.0804 109.546C63.6619 113.922 60.3796 117.492 56.2336 120.256C52.2028 122.905 47.1355 124.23 41.0316 124.23C36.6553 124.23 33.2003 123.654 30.6666 122.502C28.1329 121.235 26.2327 119.796 24.9659 118.183V160.162L0.0898438 166.381V30.4263H24.9659ZM32.7396 109.2C35.734 109.2 38.2676 108.221 40.3406 106.264C42.4136 104.191 44.026 101.542 45.1776 98.3171C46.4445 95.0924 47.3082 91.5222 47.7689 87.6066C48.3447 83.5757 48.6326 79.6025 48.6326 75.6868C48.6326 69.3526 48.0568 64.3429 46.9051 60.6575C45.8686 56.9722 44.6018 54.2658 43.1046 52.5383C41.6075 50.6956 40.1103 49.5439 38.6131 49.0833C37.2311 48.6226 36.137 48.3923 35.3309 48.3923C33.2579 48.3923 31.2425 49.1409 29.2846 50.638C27.3268 52.02 25.8872 54.1506 24.9659 57.0298V105.227C25.5417 106.148 26.463 107.07 27.7299 107.991C28.9967 108.797 30.6666 109.2 32.7396 109.2Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M188.176 31.4627C191.055 42.5188 193.588 51.5593 195.777 58.5845C197.965 65.4945 199.807 71.3105 201.305 76.0323C202.917 80.7541 204.126 84.9001 204.932 88.4703C205.854 92.0405 206.314 96.0137 206.314 100.39C208.272 99.1232 210.172 97.7988 212.015 96.4168C213.858 94.9196 215.413 93.5376 216.679 92.2708H223.935C220.825 96.9926 217.543 100.908 214.088 104.018C210.633 107.012 207.293 109.661 204.069 111.964C201.996 116.456 198.829 119.623 194.567 121.466C190.306 123.308 185.872 124.23 181.266 124.23C176.083 124.23 171.649 123.539 167.964 122.157C164.279 120.659 161.227 118.702 158.808 116.283C156.505 113.749 154.777 110.87 153.626 107.646C152.474 104.421 151.898 101.023 151.898 97.4533C151.898 93.5376 152.819 90.4857 154.662 88.2975C156.62 85.9942 158.866 84.8426 161.399 84.8426C168.424 84.8426 171.937 87.6641 171.937 93.3073C171.937 95.15 171.304 96.7047 170.037 97.9716C168.77 99.2384 167.158 99.8718 165.2 99.8718C164.278 99.8718 163.3 99.7566 162.263 99.5263C161.342 99.1808 160.593 98.5474 160.017 97.6261C160.939 101.657 162.436 104.824 164.509 107.127C166.697 109.431 169.461 110.582 172.801 110.582C175.68 110.582 177.811 109.891 179.193 108.509C180.575 107.012 181.266 104.478 181.266 100.908C181.266 97.1078 180.92 93.7104 180.229 90.7161C179.653 87.6066 178.732 84.2091 177.465 80.5238C176.198 76.8385 174.644 72.4621 172.801 67.3948C170.958 62.2123 168.885 55.5326 166.582 47.3558C160.823 59.6786 153.222 67.5675 143.779 71.0225C143.779 71.9439 143.779 72.8652 143.779 73.7865C143.894 74.5927 143.952 75.4565 143.952 76.3778C143.952 83.0575 143.376 89.334 142.224 95.2076C141.072 100.966 139.115 106.033 136.351 110.41C133.702 114.671 130.247 118.068 125.986 120.602C121.724 123.02 116.484 124.23 110.265 124.23C106.004 124.23 101.916 123.596 98 122.329C94.1995 120.947 90.8021 118.759 87.8078 115.765C84.8134 112.655 82.3949 108.624 80.5523 103.672C78.8248 98.605 77.961 92.4436 77.961 85.188C77.961 80.2359 78.4793 74.9382 79.5158 69.295C80.5523 63.5367 82.4525 58.1814 85.2165 53.2293C87.9805 48.2771 91.7234 44.1887 96.4453 40.964C101.282 37.6242 107.444 35.9543 114.93 35.9543C122.646 35.9543 128.807 38.0273 133.414 42.1733C138.136 46.3193 141.303 52.9989 142.915 62.2123C146.946 61.2909 150.574 58.5269 153.798 53.9203C157.138 49.1984 160.305 42.8643 163.3 34.9177L188.176 31.4627ZM115.102 107.991C117.521 107.991 119.594 107.185 121.321 105.573C123.164 103.845 124.661 101.542 125.813 98.6626C126.964 95.6682 127.771 92.1556 128.231 88.1248C128.807 84.094 129.095 79.7176 129.095 74.9958V72.75C124.488 71.7135 122.185 68.3161 122.185 62.5578C122.185 58.8724 123.682 56.4539 126.677 55.3023C125.41 51.6169 123.855 49.1984 122.012 48.0468C120.285 46.8951 118.788 46.3193 117.521 46.3193C114.987 46.3193 112.799 47.5285 110.956 49.947C109.229 52.2504 107.789 55.2447 106.638 58.93C105.486 62.5002 104.622 66.4734 104.046 70.8498C103.586 75.2261 103.355 79.4297 103.355 83.4605C103.355 88.6431 103.701 92.8466 104.392 96.0713C105.198 99.296 106.177 101.772 107.329 103.5C108.48 105.227 109.747 106.436 111.129 107.127C112.511 107.703 113.835 107.991 115.102 107.991Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M239.554 9.52348V36.818H250.092V43.728H239.554V95.5531C239.554 100.39 240.187 103.615 241.454 105.227C242.836 106.724 245.197 107.473 248.537 107.473C251.877 107.473 254.641 106.033 256.829 103.154C259.132 100.275 260.457 96.6471 260.802 92.2708H268.058C267.136 99.296 265.524 104.939 263.221 109.2C260.917 113.346 258.326 116.571 255.447 118.874C252.568 121.062 249.631 122.502 246.637 123.193C243.642 123.884 240.993 124.23 238.69 124.23C229.822 124.23 223.603 121.811 220.033 116.974C216.463 112.022 214.678 105.515 214.678 97.4533V43.728H209.15V36.818H214.678V12.9785L239.554 9.52348Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M258.833 13.8422C258.833 10.0417 260.158 6.81706 262.806 4.16823C265.455 1.40422 268.68 0.0222168 272.48 0.0222168C276.281 0.0222168 279.506 1.40422 282.154 4.16823C284.918 6.81706 286.3 10.0417 286.3 13.8422C286.3 17.6427 284.918 20.8674 282.154 23.5162C279.506 26.1651 276.281 27.4895 272.48 27.4895C268.68 27.4895 265.455 26.1651 262.806 23.5162C260.158 20.8674 258.833 17.6427 258.833 13.8422ZM285.609 36.818V95.5531C285.609 100.39 286.243 103.615 287.51 105.227C288.892 106.724 291.253 107.473 294.592 107.473C296.09 107.473 297.184 107.358 297.875 107.127C298.681 106.897 299.372 106.667 299.948 106.436C300.063 107.012 300.12 107.588 300.12 108.164C300.12 108.74 300.12 109.315 300.12 109.891C300.12 112.77 299.602 115.131 298.566 116.974C297.644 118.817 296.377 120.314 294.765 121.466C293.268 122.502 291.598 123.193 289.755 123.539C288.028 123.999 286.358 124.23 284.746 124.23C275.878 124.23 269.659 121.811 266.089 116.974C262.518 112.022 260.733 105.515 260.733 97.4533V36.818H285.609ZM351.773 107.473C350.391 107.358 349.354 106.897 348.663 106.091C347.972 105.169 347.627 104.133 347.627 102.981C347.627 101.484 348.26 100.045 349.527 98.6626C350.794 97.1654 352.867 96.4168 355.746 96.4168C358.971 96.4168 361.389 97.5109 363.001 99.6991C364.614 101.772 365.42 104.248 365.42 107.127C365.42 108.97 365.074 110.87 364.383 112.828C363.692 114.671 362.598 116.398 361.101 118.011C359.604 119.508 357.761 120.775 355.573 121.811C353.385 122.732 350.851 123.193 347.972 123.193H300.293L334.152 46.1465H321.369C318.835 46.1465 316.704 46.3193 314.977 46.6648C313.365 46.8951 312.558 47.5285 312.558 48.565C312.558 49.0257 312.674 49.256 312.904 49.256C313.249 49.256 313.595 49.3712 313.94 49.6015C314.401 49.8318 314.747 50.2925 314.977 50.9835C315.322 51.6745 315.495 52.8838 315.495 54.6113C315.495 57.1449 314.689 58.9876 313.077 60.1393C311.579 61.2909 309.852 61.8668 307.894 61.8668C305.591 61.8668 303.345 61.1182 301.157 59.621C299.084 58.0087 298.047 55.5902 298.047 52.3655C298.047 50.638 298.393 48.9105 299.084 47.183C299.775 45.3403 300.811 43.6704 302.193 42.1733C303.575 40.5609 305.303 39.2941 307.376 38.3728C309.449 37.3363 311.867 36.818 314.631 36.818H362.138L329.142 109.891C329.833 109.891 330.812 109.949 332.079 110.064C333.346 110.179 334.67 110.294 336.052 110.41C337.55 110.525 338.989 110.64 340.371 110.755C341.868 110.87 343.193 110.928 344.344 110.928C346.417 110.928 348.145 110.697 349.527 110.237C351.024 109.776 351.773 108.855 351.773 107.473Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
) : (
|
||||
'Gitroom'
|
||||
)}
|
||||
</div>
|
||||
</Link>
|
||||
{user?.orgId &&
|
||||
(user.tier !== 'FREE' || !isGeneral || !billingEnabled) ? (
|
||||
<TopMenu />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<div
|
||||
id="systray-buttons"
|
||||
className="flex items-center justify-self-end gap-[8px] order-2 md:order-3"
|
||||
>
|
||||
<ModeComponent />
|
||||
<SettingsComponent />
|
||||
<NotificationComponent />
|
||||
<OrganizationSelector />
|
||||
</div>
|
||||
</nav>
|
||||
<div className="flex-1 flex">
|
||||
<div className="flex-1 rounded-3xl px-0 py-[17px] flex flex-col">
|
||||
{user.tier === 'FREE' && isGeneral && billingEnabled ? (
|
||||
<>
|
||||
<div className="text-center mb-[20px] text-xl [@media(max-width:1024px)]:text-xl">
|
||||
<h1 className="text-3xl [@media(max-width:1024px)]:text-xl">
|
||||
Join 1000+ Entrepreneurs Who Use Postiz
|
||||
<br />
|
||||
To Manage All Your Social Media Channels
|
||||
</h1>
|
||||
<br />
|
||||
{user?.allowTrial && (
|
||||
<div className="table mx-auto">
|
||||
<div className="flex gap-[5px] items-center">
|
||||
<div>
|
||||
|
|
@ -203,20 +212,20 @@ export const LayoutSettings = ({ children }: { children: ReactNode }) => {
|
|||
<div>Cancel anytime, hassle-free</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<BillingComponent />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Title />
|
||||
<div className="flex flex-1 flex-col">{children}</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<BillingComponent />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Title />
|
||||
<div className="flex flex-1 flex-col">{children}</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</MantineWrapper>
|
||||
</ContextWrapper>
|
||||
</div>
|
||||
</MantineWrapper>
|
||||
</CopilotKit>
|
||||
</ContextWrapper>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -89,112 +89,112 @@ export const SettingsPopup: FC<{ getRef?: Ref<any> }> = (props) => {
|
|||
!getRef && 'p-[32px] rounded-[4px] border border-customColor6'
|
||||
)}
|
||||
>
|
||||
{!getRef && (
|
||||
<button
|
||||
onClick={close}
|
||||
className="outline-none absolute right-[20px] top-[20px] mantine-UnstyledButton-root mantine-ActionIcon-root hover:bg-tableBorder cursor-pointer mantine-Modal-close mantine-1dcetaa"
|
||||
type="button"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 15 15"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
>
|
||||
<path
|
||||
d="M11.7816 4.03157C12.0062 3.80702 12.0062 3.44295 11.7816 3.2184C11.5571 2.99385 11.193 2.99385 10.9685 3.2184L7.50005 6.68682L4.03164 3.2184C3.80708 2.99385 3.44301 2.99385 3.21846 3.2184C2.99391 3.44295 2.99391 3.80702 3.21846 4.03157L6.68688 7.49999L3.21846 10.9684C2.99391 11.193 2.99391 11.557 3.21846 11.7816C3.44301 12.0061 3.80708 12.0061 4.03164 11.7816L7.50005 8.31316L10.9685 11.7816C11.193 12.0061 11.5571 12.0061 11.7816 11.7816C12.0062 11.557 12.0062 11.193 11.7816 10.9684L8.31322 7.49999L11.7816 4.03157Z"
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
></path>
|
||||
</svg>
|
||||
</button>
|
||||
)}
|
||||
{!getRef && (
|
||||
<div className="text-[24px] font-[600]">Profile Settings</div>
|
||||
)}
|
||||
<div className="flex flex-col gap-[4px]">
|
||||
<div className="text-[20px] font-[500]">Profile</div>
|
||||
<div className="text-[14px] text-customColor18 font-[400]">
|
||||
Add profile information
|
||||
</div>
|
||||
</div>
|
||||
<div className="rounded-[4px] border border-customColor6 p-[24px] flex flex-col">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="w-[455px]">
|
||||
<Input label="Full Name" name="fullname" />
|
||||
</div>
|
||||
<div className="flex gap-[8px] mb-[10px]">
|
||||
<div className="w-[48px] h-[48px] rounded-full bg-customColor38">
|
||||
{!!picture?.path && (
|
||||
<img
|
||||
src={picture?.path}
|
||||
alt="profile"
|
||||
className="w-full h-full rounded-full"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col gap-[2px]">
|
||||
<div className="text-[14px]">Profile Picture</div>
|
||||
<div className="flex gap-[8px]">
|
||||
<button
|
||||
className="h-[24px] w-[120px] bg-forth rounded-[4px] flex justify-center gap-[4px] items-center cursor-pointer"
|
||||
type="button"
|
||||
>
|
||||
<div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="14"
|
||||
height="14"
|
||||
viewBox="0 0 14 14"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M12.25 8.3126V11.3751C12.25 11.6072 12.1578 11.8297 11.9937 11.9938C11.8296 12.1579 11.6071 12.2501 11.375 12.2501H2.625C2.39294 12.2501 2.17038 12.1579 2.00628 11.9938C1.84219 11.8297 1.75 11.6072 1.75 11.3751V8.3126C1.75 8.19657 1.79609 8.08529 1.87814 8.00324C1.96019 7.92119 2.07147 7.8751 2.1875 7.8751C2.30353 7.8751 2.41481 7.92119 2.49686 8.00324C2.57891 8.08529 2.625 8.19657 2.625 8.3126V11.3751H11.375V8.3126C11.375 8.19657 11.4211 8.08529 11.5031 8.00324C11.5852 7.92119 11.6965 7.8751 11.8125 7.8751C11.9285 7.8751 12.0398 7.92119 12.1219 8.00324C12.2039 8.08529 12.25 8.19657 12.25 8.3126ZM5.12203 4.68463L6.5625 3.24362V8.3126C6.5625 8.42863 6.60859 8.53991 6.69064 8.62196C6.77269 8.70401 6.88397 8.7501 7 8.7501C7.11603 8.7501 7.22731 8.70401 7.30936 8.62196C7.39141 8.53991 7.4375 8.42863 7.4375 8.3126V3.24362L8.87797 4.68463C8.96006 4.76672 9.0714 4.81284 9.1875 4.81284C9.3036 4.81284 9.41494 4.76672 9.49703 4.68463C9.57912 4.60254 9.62524 4.4912 9.62524 4.3751C9.62524 4.259 9.57912 4.14766 9.49703 4.06557L7.30953 1.87807C7.2689 1.83739 7.22065 1.80512 7.16754 1.78311C7.11442 1.76109 7.05749 1.74976 7 1.74976C6.94251 1.74976 6.88558 1.76109 6.83246 1.78311C6.77935 1.80512 6.7311 1.83739 6.69047 1.87807L4.50297 4.06557C4.42088 4.14766 4.37476 4.259 4.37476 4.3751C4.37476 4.4912 4.42088 4.60254 4.50297 4.68463C4.58506 4.76672 4.6964 4.81284 4.8125 4.81284C4.9286 4.81284 5.03994 4.76672 5.12203 4.68463Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div className="text-[12px] text-white" onClick={openMedia}>
|
||||
Upload image
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
className="h-[24px] w-[88px] rounded-[4px] border-2 border-customColor21 hover:text-red-600 flex justify-center items-center gap-[4px]"
|
||||
type="button"
|
||||
>
|
||||
<div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="14"
|
||||
height="14"
|
||||
viewBox="0 0 14 14"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M11.8125 2.625H9.625V2.1875C9.625 1.8394 9.48672 1.50556 9.24058 1.25942C8.99444 1.01328 8.6606 0.875 8.3125 0.875H5.6875C5.3394 0.875 5.00556 1.01328 4.75942 1.25942C4.51328 1.50556 4.375 1.8394 4.375 2.1875V2.625H2.1875C2.07147 2.625 1.96019 2.67109 1.87814 2.75314C1.79609 2.83519 1.75 2.94647 1.75 3.0625C1.75 3.17853 1.79609 3.28981 1.87814 3.37186C1.96019 3.45391 2.07147 3.5 2.1875 3.5H2.625V11.375C2.625 11.6071 2.71719 11.8296 2.88128 11.9937C3.04538 12.1578 3.26794 12.25 3.5 12.25H10.5C10.7321 12.25 10.9546 12.1578 11.1187 11.9937C11.2828 11.8296 11.375 11.6071 11.375 11.375V3.5H11.8125C11.9285 3.5 12.0398 3.45391 12.1219 3.37186C12.2039 3.28981 12.25 3.17853 12.25 3.0625C12.25 2.94647 12.2039 2.83519 12.1219 2.75314C12.0398 2.67109 11.9285 2.625 11.8125 2.625ZM5.25 2.1875C5.25 2.07147 5.29609 1.96019 5.37814 1.87814C5.46019 1.79609 5.57147 1.75 5.6875 1.75H8.3125C8.42853 1.75 8.53981 1.79609 8.62186 1.87814C8.70391 1.96019 8.75 2.07147 8.75 2.1875V2.625H5.25V2.1875ZM10.5 11.375H3.5V3.5H10.5V11.375ZM6.125 5.6875V9.1875C6.125 9.30353 6.07891 9.41481 5.99686 9.49686C5.91481 9.57891 5.80353 9.625 5.6875 9.625C5.57147 9.625 5.46019 9.57891 5.37814 9.49686C5.29609 9.41481 5.25 9.30353 5.25 9.1875V5.6875C5.25 5.57147 5.29609 5.46019 5.37814 5.37814C5.46019 5.29609 5.57147 5.25 5.6875 5.25C5.80353 5.25 5.91481 5.29609 5.99686 5.37814C6.07891 5.46019 6.125 5.57147 6.125 5.6875ZM8.75 5.6875V9.1875C8.75 9.30353 8.70391 9.41481 8.62186 9.49686C8.53981 9.57891 8.42853 9.625 8.3125 9.625C8.19647 9.625 8.08519 9.57891 8.00314 9.49686C7.92109 9.41481 7.875 9.30353 7.875 9.1875V5.6875C7.875 5.57147 7.92109 5.46019 8.00314 5.37814C8.08519 5.29609 8.19647 5.25 8.3125 5.25C8.42853 5.25 8.53981 5.29609 8.62186 5.37814C8.70391 5.46019 8.75 5.57147 8.75 5.6875Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div className="text-[12px] " onClick={remove}>
|
||||
Remove
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Textarea label="Bio" name="bio" className="resize-none" />
|
||||
</div>
|
||||
</div>
|
||||
{!getRef && (
|
||||
<div className="justify-end flex">
|
||||
<Button type="submit" className='rounded-md'>Save</Button>
|
||||
</div>
|
||||
)}
|
||||
{/*{!getRef && (*/}
|
||||
{/* <button*/}
|
||||
{/* onClick={close}*/}
|
||||
{/* className="outline-none absolute right-[20px] top-[20px] mantine-UnstyledButton-root mantine-ActionIcon-root hover:bg-tableBorder cursor-pointer mantine-Modal-close mantine-1dcetaa"*/}
|
||||
{/* type="button"*/}
|
||||
{/* >*/}
|
||||
{/* <svg*/}
|
||||
{/* viewBox="0 0 15 15"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* width="16"*/}
|
||||
{/* height="16"*/}
|
||||
{/* >*/}
|
||||
{/* <path*/}
|
||||
{/* d="M11.7816 4.03157C12.0062 3.80702 12.0062 3.44295 11.7816 3.2184C11.5571 2.99385 11.193 2.99385 10.9685 3.2184L7.50005 6.68682L4.03164 3.2184C3.80708 2.99385 3.44301 2.99385 3.21846 3.2184C2.99391 3.44295 2.99391 3.80702 3.21846 4.03157L6.68688 7.49999L3.21846 10.9684C2.99391 11.193 2.99391 11.557 3.21846 11.7816C3.44301 12.0061 3.80708 12.0061 4.03164 11.7816L7.50005 8.31316L10.9685 11.7816C11.193 12.0061 11.5571 12.0061 11.7816 11.7816C12.0062 11.557 12.0062 11.193 11.7816 10.9684L8.31322 7.49999L11.7816 4.03157Z"*/}
|
||||
{/* fill="currentColor"*/}
|
||||
{/* fillRule="evenodd"*/}
|
||||
{/* clipRule="evenodd"*/}
|
||||
{/* ></path>*/}
|
||||
{/* </svg>*/}
|
||||
{/* </button>*/}
|
||||
{/*)}*/}
|
||||
{/*{!getRef && (*/}
|
||||
{/* <div className="text-[24px] font-[600]">Profile Settings</div>*/}
|
||||
{/*)}*/}
|
||||
{/*<div className="flex flex-col gap-[4px]">*/}
|
||||
{/* <div className="text-[20px] font-[500]">Profile</div>*/}
|
||||
{/* <div className="text-[14px] text-customColor18 font-[400]">*/}
|
||||
{/* Add profile information*/}
|
||||
{/* </div>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className="rounded-[4px] border border-customColor6 p-[24px] flex flex-col">*/}
|
||||
{/* <div className="flex justify-between items-center">*/}
|
||||
{/* <div className="w-[455px]">*/}
|
||||
{/* <Input label="Full Name" name="fullname" />*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="flex gap-[8px] mb-[10px]">*/}
|
||||
{/* <div className="w-[48px] h-[48px] rounded-full bg-customColor38">*/}
|
||||
{/* {!!picture?.path && (*/}
|
||||
{/* <img*/}
|
||||
{/* src={picture?.path}*/}
|
||||
{/* alt="profile"*/}
|
||||
{/* className="w-full h-full rounded-full"*/}
|
||||
{/* />*/}
|
||||
{/* )}*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="flex flex-col gap-[2px]">*/}
|
||||
{/* <div className="text-[14px]">Profile Picture</div>*/}
|
||||
{/* <div className="flex gap-[8px]">*/}
|
||||
{/* <button*/}
|
||||
{/* className="h-[24px] w-[120px] bg-forth rounded-[4px] flex justify-center gap-[4px] items-center cursor-pointer"*/}
|
||||
{/* type="button"*/}
|
||||
{/* >*/}
|
||||
{/* <div>*/}
|
||||
{/* <svg*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* width="14"*/}
|
||||
{/* height="14"*/}
|
||||
{/* viewBox="0 0 14 14"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* >*/}
|
||||
{/* <path*/}
|
||||
{/* d="M12.25 8.3126V11.3751C12.25 11.6072 12.1578 11.8297 11.9937 11.9938C11.8296 12.1579 11.6071 12.2501 11.375 12.2501H2.625C2.39294 12.2501 2.17038 12.1579 2.00628 11.9938C1.84219 11.8297 1.75 11.6072 1.75 11.3751V8.3126C1.75 8.19657 1.79609 8.08529 1.87814 8.00324C1.96019 7.92119 2.07147 7.8751 2.1875 7.8751C2.30353 7.8751 2.41481 7.92119 2.49686 8.00324C2.57891 8.08529 2.625 8.19657 2.625 8.3126V11.3751H11.375V8.3126C11.375 8.19657 11.4211 8.08529 11.5031 8.00324C11.5852 7.92119 11.6965 7.8751 11.8125 7.8751C11.9285 7.8751 12.0398 7.92119 12.1219 8.00324C12.2039 8.08529 12.25 8.19657 12.25 8.3126ZM5.12203 4.68463L6.5625 3.24362V8.3126C6.5625 8.42863 6.60859 8.53991 6.69064 8.62196C6.77269 8.70401 6.88397 8.7501 7 8.7501C7.11603 8.7501 7.22731 8.70401 7.30936 8.62196C7.39141 8.53991 7.4375 8.42863 7.4375 8.3126V3.24362L8.87797 4.68463C8.96006 4.76672 9.0714 4.81284 9.1875 4.81284C9.3036 4.81284 9.41494 4.76672 9.49703 4.68463C9.57912 4.60254 9.62524 4.4912 9.62524 4.3751C9.62524 4.259 9.57912 4.14766 9.49703 4.06557L7.30953 1.87807C7.2689 1.83739 7.22065 1.80512 7.16754 1.78311C7.11442 1.76109 7.05749 1.74976 7 1.74976C6.94251 1.74976 6.88558 1.76109 6.83246 1.78311C6.77935 1.80512 6.7311 1.83739 6.69047 1.87807L4.50297 4.06557C4.42088 4.14766 4.37476 4.259 4.37476 4.3751C4.37476 4.4912 4.42088 4.60254 4.50297 4.68463C4.58506 4.76672 4.6964 4.81284 4.8125 4.81284C4.9286 4.81284 5.03994 4.76672 5.12203 4.68463Z"*/}
|
||||
{/* fill="white"*/}
|
||||
{/* />*/}
|
||||
{/* </svg>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="text-[12px] text-white" onClick={openMedia}>*/}
|
||||
{/* Upload image*/}
|
||||
{/* </div>*/}
|
||||
{/* </button>*/}
|
||||
{/* <button*/}
|
||||
{/* className="h-[24px] w-[88px] rounded-[4px] border-2 border-customColor21 hover:text-red-600 flex justify-center items-center gap-[4px]"*/}
|
||||
{/* type="button"*/}
|
||||
{/* >*/}
|
||||
{/* <div>*/}
|
||||
{/* <svg*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* width="14"*/}
|
||||
{/* height="14"*/}
|
||||
{/* viewBox="0 0 14 14"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* >*/}
|
||||
{/* <path*/}
|
||||
{/* d="M11.8125 2.625H9.625V2.1875C9.625 1.8394 9.48672 1.50556 9.24058 1.25942C8.99444 1.01328 8.6606 0.875 8.3125 0.875H5.6875C5.3394 0.875 5.00556 1.01328 4.75942 1.25942C4.51328 1.50556 4.375 1.8394 4.375 2.1875V2.625H2.1875C2.07147 2.625 1.96019 2.67109 1.87814 2.75314C1.79609 2.83519 1.75 2.94647 1.75 3.0625C1.75 3.17853 1.79609 3.28981 1.87814 3.37186C1.96019 3.45391 2.07147 3.5 2.1875 3.5H2.625V11.375C2.625 11.6071 2.71719 11.8296 2.88128 11.9937C3.04538 12.1578 3.26794 12.25 3.5 12.25H10.5C10.7321 12.25 10.9546 12.1578 11.1187 11.9937C11.2828 11.8296 11.375 11.6071 11.375 11.375V3.5H11.8125C11.9285 3.5 12.0398 3.45391 12.1219 3.37186C12.2039 3.28981 12.25 3.17853 12.25 3.0625C12.25 2.94647 12.2039 2.83519 12.1219 2.75314C12.0398 2.67109 11.9285 2.625 11.8125 2.625ZM5.25 2.1875C5.25 2.07147 5.29609 1.96019 5.37814 1.87814C5.46019 1.79609 5.57147 1.75 5.6875 1.75H8.3125C8.42853 1.75 8.53981 1.79609 8.62186 1.87814C8.70391 1.96019 8.75 2.07147 8.75 2.1875V2.625H5.25V2.1875ZM10.5 11.375H3.5V3.5H10.5V11.375ZM6.125 5.6875V9.1875C6.125 9.30353 6.07891 9.41481 5.99686 9.49686C5.91481 9.57891 5.80353 9.625 5.6875 9.625C5.57147 9.625 5.46019 9.57891 5.37814 9.49686C5.29609 9.41481 5.25 9.30353 5.25 9.1875V5.6875C5.25 5.57147 5.29609 5.46019 5.37814 5.37814C5.46019 5.29609 5.57147 5.25 5.6875 5.25C5.80353 5.25 5.91481 5.29609 5.99686 5.37814C6.07891 5.46019 6.125 5.57147 6.125 5.6875ZM8.75 5.6875V9.1875C8.75 9.30353 8.70391 9.41481 8.62186 9.49686C8.53981 9.57891 8.42853 9.625 8.3125 9.625C8.19647 9.625 8.08519 9.57891 8.00314 9.49686C7.92109 9.41481 7.875 9.30353 7.875 9.1875V5.6875C7.875 5.57147 7.92109 5.46019 8.00314 5.37814C8.08519 5.29609 8.19647 5.25 8.3125 5.25C8.42853 5.25 8.53981 5.29609 8.62186 5.37814C8.70391 5.46019 8.75 5.57147 8.75 5.6875Z"*/}
|
||||
{/* fill="currentColor"*/}
|
||||
{/* />*/}
|
||||
{/* </svg>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="text-[12px] " onClick={remove}>*/}
|
||||
{/* Remove*/}
|
||||
{/* </div>*/}
|
||||
{/* </button>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div>*/}
|
||||
{/* <Textarea label="Bio" name="bio" className="resize-none" />*/}
|
||||
{/* </div>*/}
|
||||
{/*</div>*/}
|
||||
{/*{!getRef && (*/}
|
||||
{/* <div className="justify-end flex">*/}
|
||||
{/* <Button type="submit" className='rounded-md'>Save</Button>*/}
|
||||
{/* </div>*/}
|
||||
{/*)}*/}
|
||||
{!!user?.tier?.team_members && isGeneral && <TeamsComponent />}
|
||||
{!!user?.tier?.public_api && isGeneral && showLogout && <PublicComponent />}
|
||||
{showLogout && <LogoutComponent />}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ export const UserContext = createContext<
|
|||
totalChannels: number;
|
||||
isLifetime?: boolean;
|
||||
impersonate: boolean;
|
||||
allowTrial: boolean;
|
||||
})
|
||||
>(undefined);
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ export const NotificationOpenComponent = () => {
|
|||
const { data, isLoading } = useSWR('notifications', loadNotifications);
|
||||
|
||||
return (
|
||||
<div id="notification-popup" className="opacity-0 animate-normalFadeDown mt-[10px] absolute w-[420px] min-h-[200px] top-[100%] right-0 bg-third text-textColor rounded-[16px] flex flex-col border border-tableBorder z-[2]">
|
||||
<div id="notification-popup" className="opacity-0 animate-normalFadeDown mt-[10px] absolute w-[420px] min-h-[200px] top-[100%] right-0 bg-third text-textColor rounded-[16px] flex flex-col border border-tableBorder z-[20]">
|
||||
<div className={`p-[16px] border-b border-tableBorder ${interClass} font-bold`}>
|
||||
Notifications
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ const Welcome: FC = () => {
|
|||
<div className="bg-sixth p-[32px] w-full max-w-[920px] mx-auto flex flex-col gap-[24px] rounded-[4px] border border-customColor6 relative">
|
||||
<h1 className="text-[24px]">Onboarding</h1>
|
||||
<div className="flex">
|
||||
<Step title="Profile" step={1} currentStep={step} lastStep={lastStep} />
|
||||
<Step title="Connect Channels" step={1} currentStep={step} lastStep={lastStep} />
|
||||
<StepSpace />
|
||||
{!isGeneral && (
|
||||
<>
|
||||
|
|
@ -168,19 +168,19 @@ const Welcome: FC = () => {
|
|||
title="Connect Github"
|
||||
step={2}
|
||||
currentStep={step}
|
||||
lastStep={4}
|
||||
lastStep={2}
|
||||
/>
|
||||
<StepSpace />
|
||||
</>
|
||||
)}
|
||||
<Step
|
||||
title="Connect Channels"
|
||||
title="Finish"
|
||||
step={3 - (isGeneral ? 1 : 0)}
|
||||
currentStep={step}
|
||||
lastStep={4}
|
||||
lastStep={2}
|
||||
/>
|
||||
<StepSpace />
|
||||
<Step title="Finish" step={4 - (isGeneral ? 1 : 0)} currentStep={step} lastStep={lastStep} />
|
||||
{/*<StepSpace />*/}
|
||||
{/*<Step title="Finish" step={4 - (isGeneral ? 1 : 0)} currentStep={step} lastStep={lastStep} />*/}
|
||||
{seller && (
|
||||
<>
|
||||
<StepSpace />
|
||||
|
|
@ -193,36 +193,25 @@ const Welcome: FC = () => {
|
|||
</>
|
||||
)}
|
||||
</div>
|
||||
{step === 1 && (
|
||||
<>
|
||||
<div>
|
||||
<SettingsPopup getRef={ref} />
|
||||
</div>
|
||||
<div className="flex justify-end gap-[8px]">
|
||||
<SkipOnboarding />
|
||||
<Button onClick={firstNext}>Next</Button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{step === 2 && !isGeneral && (
|
||||
{step === 1 && !isGeneral && (
|
||||
<div>
|
||||
<GithubOnboarding />
|
||||
<div className="flex justify-end gap-[8px]">
|
||||
<SkipOnboarding />
|
||||
{/*<SkipOnboarding />*/}
|
||||
<Button onClick={nextStep()}>Next</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{step === 2 - (isGeneral ? 1 : 0) && (
|
||||
<div>
|
||||
<ConnectChannels />
|
||||
<div className="flex justify-end gap-[8px]">
|
||||
{/*<SkipOnboarding />*/}
|
||||
<Button onClick={nextStep()}>Next</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{step === 3 - (isGeneral ? 1 : 0) && (
|
||||
<div>
|
||||
<ConnectChannels />
|
||||
<div className="flex justify-end gap-[8px]">
|
||||
<SkipOnboarding />
|
||||
<Button onClick={nextStep()}>Next</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{step === 4 - (isGeneral ? 1 : 0) && (
|
||||
<div className="items-center justify-center flex flex-col gap-[24px]">
|
||||
<div className="items-center justify-center flex flex-col">
|
||||
<img src="/success.svg" alt="success" />
|
||||
|
|
@ -238,14 +227,14 @@ const Welcome: FC = () => {
|
|||
<Button onClick={goToLaunches}>Schedule a new post</Button>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-[8px]">
|
||||
<Button onClick={buyPosts}>Buy posts from Influencers</Button>
|
||||
<Button onClick={sellPosts}>Sell your services</Button>
|
||||
</div>
|
||||
{/*<div className="grid grid-cols-2 gap-[8px]">*/}
|
||||
{/* /!*<Button onClick={buyPosts}>Buy posts from Influencers</Button>*!/*/}
|
||||
{/* /!*<Button onClick={sellPosts}>Sell your services</Button>*!/*/}
|
||||
{/*</div>*/}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{step === 5 - (isGeneral ? 1 : 0) && (
|
||||
{step === 4 - (isGeneral ? 1 : 0) && (
|
||||
<div>
|
||||
<div className="text-[24px] mb-[24px]">To sell posts you would have to:</div>
|
||||
<ul>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
'use client';
|
||||
import { useUser } from '@gitroom/frontend/components/layout/user.context';
|
||||
import { Button } from '@gitroom/react/form/button';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
export const CommentsComponents = () => {
|
||||
const user = useUser();
|
||||
|
||||
const goToComments = useCallback(() => {
|
||||
window.location.href = `/auth?returnUrl=${window.location.href}`;
|
||||
}, []);
|
||||
|
||||
if (!user?.id) {
|
||||
return <Button onClick={goToComments}>Login to add comments</Button>
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mb-6 flex space-x-3">
|
||||
<div className="flex-1 space-y-2">
|
||||
<textarea
|
||||
className="flex w-full rounded-md border border-input px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 min-h-[80px] resize-none bg-transparent text-white placeholder-gray-500 focus:ring-0"
|
||||
placeholder="What's happening?"
|
||||
defaultValue={''}
|
||||
/>
|
||||
<div className="flex justify-end">
|
||||
<Button>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={24}
|
||||
height={24}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth={2}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="lucide lucide-send mr-2 h-4 w-4"
|
||||
>
|
||||
<path d="m22 2-7 20-4-9-9-4Z" />
|
||||
<path d="M22 2 11 13" />
|
||||
</svg>
|
||||
Post
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-lg font-semibold">Comments</h3>
|
||||
<div className="flex space-x-3 border-t border-tableBorder py-3">
|
||||
<div className="flex-1 space-y-1">
|
||||
<div className="flex items-center space-x-2">
|
||||
<h3 className="text-sm font-semibold">Alice Smith</h3>
|
||||
<span className="text-xs text-gray-500">· 1h</span>
|
||||
</div>
|
||||
<p className="text-sm text-gray-300">
|
||||
Looks great! Congrats on the launch!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
'use client';
|
||||
|
||||
import useSWR from 'swr';
|
||||
import { ContextWrapper } from '@gitroom/frontend/components/layout/user.context';
|
||||
import { ReactNode, useCallback } from 'react';
|
||||
import { useFetch } from '@gitroom/helpers/utils/custom.fetch';
|
||||
|
||||
export const PreviewWrapper = ({ children }: { children: ReactNode }) => {
|
||||
const fetch = useFetch();
|
||||
|
||||
const load = useCallback(async (path: string) => {
|
||||
return await (await fetch(path)).json();
|
||||
}, []);
|
||||
|
||||
const { data: user } = useSWR('/user/self', load, {
|
||||
revalidateOnFocus: false,
|
||||
revalidateOnReconnect: false,
|
||||
revalidateIfStale: false,
|
||||
refreshWhenOffline: false,
|
||||
refreshWhenHidden: false,
|
||||
});
|
||||
|
||||
return <ContextWrapper user={user}>{children}</ContextWrapper>;
|
||||
};
|
||||
|
|
@ -7,7 +7,7 @@ import { internalFetch } from '@gitroom/helpers/utils/internal.fetch';
|
|||
export async function middleware(request: NextRequest) {
|
||||
const nextUrl = request.nextUrl;
|
||||
const authCookie = request.cookies.get('auth');
|
||||
if (nextUrl.pathname.startsWith('/uploads/')) {
|
||||
if (nextUrl.pathname.startsWith('/uploads/') || nextUrl.pathname.startsWith('/p/')) {
|
||||
return NextResponse.next();
|
||||
}
|
||||
// If the URL is logout, delete the cookie and redirect to login
|
||||
|
|
|
|||
|
|
@ -131,11 +131,11 @@ module.exports = {
|
|||
'100%': { overflow: 'hidden' },
|
||||
},
|
||||
fadeDown: {
|
||||
'0%': { opacity: 0, transform: 'translateY(-30px)' },
|
||||
'10%': { opacity: 1, transform: 'translateY(0)' },
|
||||
'85%': { opacity: 1, transform: 'translateY(0)' },
|
||||
'90%': { opacity: 1, transform: 'translateY(10px)' },
|
||||
'100%': { opacity: 0, transform: 'translateY(-30px)' },
|
||||
'0%': { opacity: 0, marginTop: -30},
|
||||
'10%': { opacity: 1, marginTop: 0 },
|
||||
'85%': { opacity: 1, marginTop: 0 },
|
||||
'90%': { opacity: 1, marginTop: 10 },
|
||||
'100%': { opacity: 0, marginTop: -30 },
|
||||
},
|
||||
normalFadeDown: {
|
||||
'0%': { opacity: 0, transform: 'translateY(-30px)' },
|
||||
|
|
|
|||
|
|
@ -3,10 +3,23 @@
|
|||
import { FC, useCallback, useEffect } from 'react';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import { useLocalStorage } from '@mantine/hooks';
|
||||
import { TrackEnum } from '@gitroom/nestjs-libraries/user/track.enum';
|
||||
import { useFireEvents } from '@gitroom/helpers/utils/use.fire.events';
|
||||
import { useTrack } from '@gitroom/react/helpers/use.track';
|
||||
|
||||
const UtmSaver: FC = () => {
|
||||
const query = useSearchParams();
|
||||
const [value, setValue] = useLocalStorage({ key: 'utm', defaultValue: '' });
|
||||
const searchParams = useSearchParams();
|
||||
const fireEvents = useFireEvents();
|
||||
const track = useTrack();
|
||||
|
||||
useEffect(() => {
|
||||
if (searchParams.get('check')) {
|
||||
fireEvents('purchase');
|
||||
track(TrackEnum.StartTrial);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const landingUrl = localStorage.getItem('landingUrl');
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import { ExtractContentService } from '@gitroom/nestjs-libraries/openai/extract.
|
|||
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';
|
||||
import { TrackService } from '@gitroom/nestjs-libraries/track/track.service';
|
||||
|
||||
@Global()
|
||||
@Module({
|
||||
|
|
@ -66,6 +67,7 @@ import { AgenciesRepository } from '@gitroom/nestjs-libraries/database/prisma/ag
|
|||
ExtractContentService,
|
||||
OpenaiService,
|
||||
EmailService,
|
||||
TrackService,
|
||||
],
|
||||
get exports() {
|
||||
return this.providers;
|
||||
|
|
|
|||
|
|
@ -207,12 +207,15 @@ export class OrganizationRepository {
|
|||
|
||||
async createOrgAndUser(
|
||||
body: Omit<CreateOrgUserDto, 'providerToken'> & { providerId?: string },
|
||||
hasEmail: boolean
|
||||
hasEmail: boolean,
|
||||
ip: string,
|
||||
userAgent: string
|
||||
) {
|
||||
return this._organization.model.organization.create({
|
||||
data: {
|
||||
name: body.company,
|
||||
apiKey: AuthService.fixedEncryption(makeId(20)),
|
||||
allowTrial: true,
|
||||
users: {
|
||||
create: {
|
||||
role: Role.SUPERADMIN,
|
||||
|
|
@ -226,6 +229,8 @@ export class OrganizationRepository {
|
|||
providerName: body.provider,
|
||||
providerId: body.providerId || '',
|
||||
timezone: 0,
|
||||
ip,
|
||||
agent: userAgent,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -242,6 +247,14 @@ export class OrganizationRepository {
|
|||
});
|
||||
}
|
||||
|
||||
getOrgByCustomerId(customerId: string) {
|
||||
return this._organization.model.organization.findFirst({
|
||||
where: {
|
||||
paymentId: customerId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async getTeam(orgId: string) {
|
||||
return this._organization.model.organization.findUnique({
|
||||
where: {
|
||||
|
|
|
|||
|
|
@ -15,11 +15,15 @@ export class OrganizationService {
|
|||
private _notificationsService: NotificationService
|
||||
) {}
|
||||
async createOrgAndUser(
|
||||
body: Omit<CreateOrgUserDto, 'providerToken'> & { providerId?: string }
|
||||
body: Omit<CreateOrgUserDto, 'providerToken'> & { providerId?: string },
|
||||
ip: string,
|
||||
userAgent: string
|
||||
) {
|
||||
return this._organizationRepository.createOrgAndUser(
|
||||
body,
|
||||
this._notificationsService.hasEmailProvider()
|
||||
this._notificationsService.hasEmailProvider(),
|
||||
ip,
|
||||
userAgent
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -56,6 +60,10 @@ export class OrganizationService {
|
|||
return this._organizationRepository.getTeam(orgId);
|
||||
}
|
||||
|
||||
getOrgByCustomerId(customerId: string) {
|
||||
return this._organizationRepository.getOrgByCustomerId(customerId);
|
||||
}
|
||||
|
||||
async inviteTeamMember(orgId: string, body: AddTeamMemberDto) {
|
||||
const timeLimit = dayjs().add(1, 'hour').format('YYYY-MM-DD HH:mm:ss');
|
||||
const id = makeId(5);
|
||||
|
|
|
|||
|
|
@ -25,13 +25,14 @@ model Organization {
|
|||
Integration Integration[]
|
||||
post Post[] @relation("organization")
|
||||
submittedPost Post[] @relation("submittedForOrg")
|
||||
allowTrial Boolean @default(false)
|
||||
Comments Comments[]
|
||||
notifications Notifications[]
|
||||
buyerOrganization MessagesGroup[]
|
||||
usedCodes UsedCodes[]
|
||||
credits Credits[]
|
||||
plugs Plugs[]
|
||||
customers Customer[]
|
||||
plugs Plugs[]
|
||||
customers Customer[]
|
||||
}
|
||||
|
||||
model User {
|
||||
|
|
@ -66,6 +67,8 @@ model User {
|
|||
payoutProblems PayoutProblems[]
|
||||
lastOnline DateTime @default(now())
|
||||
agencies SocialMediaAgency[]
|
||||
ip String?
|
||||
agent String?
|
||||
|
||||
@@unique([email, providerName])
|
||||
@@index([lastReadNotifications])
|
||||
|
|
|
|||
|
|
@ -64,6 +64,17 @@ export class SubscriptionRepository {
|
|||
});
|
||||
}
|
||||
|
||||
getCustomerIdByOrgId(organizationId: string) {
|
||||
return this._organization.model.organization.findFirst({
|
||||
where: {
|
||||
id: organizationId,
|
||||
},
|
||||
select: {
|
||||
paymentId: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
checkSubscription(organizationId: string, subscriptionId: string) {
|
||||
return this._subscription.model.subscription.findFirst({
|
||||
where: {
|
||||
|
|
@ -158,6 +169,15 @@ export class SubscriptionRepository {
|
|||
},
|
||||
});
|
||||
|
||||
await this._organization.model.organization.update({
|
||||
where: {
|
||||
id: findOrg.id,
|
||||
},
|
||||
data: {
|
||||
allowTrial: false,
|
||||
},
|
||||
});
|
||||
|
||||
if (code) {
|
||||
await this._usedCodes.model.usedCodes.create({
|
||||
data: {
|
||||
|
|
|
|||
|
|
@ -6,13 +6,14 @@ import { OrganizationService } from '@gitroom/nestjs-libraries/database/prisma/o
|
|||
import { Organization } from '@prisma/client';
|
||||
import dayjs from 'dayjs';
|
||||
import { makeId } from '@gitroom/nestjs-libraries/services/make.is';
|
||||
import { StripeService } from '@gitroom/nestjs-libraries/services/stripe.service';
|
||||
|
||||
@Injectable()
|
||||
export class SubscriptionService {
|
||||
constructor(
|
||||
private readonly _subscriptionRepository: SubscriptionRepository,
|
||||
private readonly _integrationService: IntegrationService,
|
||||
private readonly _organizationService: OrganizationService
|
||||
private readonly _organizationService: OrganizationService,
|
||||
) {}
|
||||
|
||||
getSubscriptionByOrganizationId(organizationId: string) {
|
||||
|
|
@ -55,8 +56,8 @@ export class SubscriptionService {
|
|||
);
|
||||
}
|
||||
|
||||
checkSubscription(organizationId: string, subscriptionId: string) {
|
||||
return this._subscriptionRepository.checkSubscription(
|
||||
async checkSubscription(organizationId: string, subscriptionId: string) {
|
||||
return await this._subscriptionRepository.checkSubscription(
|
||||
organizationId,
|
||||
subscriptionId
|
||||
);
|
||||
|
|
@ -197,9 +198,7 @@ export class SubscriptionService {
|
|||
'MONTHLY',
|
||||
null,
|
||||
undefined,
|
||||
orgId
|
||||
orgId
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ import { capitalize, groupBy } from 'lodash';
|
|||
import { MessagesService } from '@gitroom/nestjs-libraries/database/prisma/marketplace/messages.service';
|
||||
import { pricing } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/pricing';
|
||||
import { AuthService } from '@gitroom/helpers/auth/auth.service';
|
||||
import { TrackService } from '@gitroom/nestjs-libraries/track/track.service';
|
||||
import { UsersService } from '@gitroom/nestjs-libraries/database/prisma/users/users.service';
|
||||
import { TrackEnum } from '@gitroom/nestjs-libraries/user/track.enum';
|
||||
|
||||
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
|
||||
apiVersion: '2024-04-10',
|
||||
|
|
@ -19,7 +22,9 @@ export class StripeService {
|
|||
constructor(
|
||||
private _subscriptionService: SubscriptionService,
|
||||
private _organizationService: OrganizationService,
|
||||
private _messagesService: MessagesService
|
||||
private _userService: UsersService,
|
||||
private _messagesService: MessagesService,
|
||||
private _trackService: TrackService
|
||||
) {}
|
||||
validateRequest(rawBody: Buffer, signature: string, endpointSecret: string) {
|
||||
return stripe.webhooks.constructEvent(rawBody, signature, endpointSecret);
|
||||
|
|
@ -40,20 +45,90 @@ export class StripeService {
|
|||
);
|
||||
}
|
||||
|
||||
createSubscription(event: Stripe.CustomerSubscriptionCreatedEvent) {
|
||||
async checkValidCard(
|
||||
event:
|
||||
| Stripe.CustomerSubscriptionCreatedEvent
|
||||
| Stripe.CustomerSubscriptionUpdatedEvent
|
||||
) {
|
||||
if (event.data.object.status === 'incomplete') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const getOrgFromCustomer =
|
||||
await this._organizationService.getOrgByCustomerId(
|
||||
event.data.object.customer as string
|
||||
);
|
||||
|
||||
if (!getOrgFromCustomer?.allowTrial) {
|
||||
return true;
|
||||
}
|
||||
|
||||
console.log('Checking card');
|
||||
|
||||
const paymentMethods = await stripe.paymentMethods.list({
|
||||
customer: event.data.object.customer as string,
|
||||
});
|
||||
|
||||
// find the last one created
|
||||
const latestMethod = paymentMethods.data.reduce((prev, current) => {
|
||||
if (prev.created < current.created) {
|
||||
return current;
|
||||
}
|
||||
return prev;
|
||||
});
|
||||
|
||||
try {
|
||||
const paymentIntent = await stripe.paymentIntents.create({
|
||||
amount: 100,
|
||||
currency: 'usd',
|
||||
payment_method: latestMethod.id,
|
||||
customer: event.data.object.customer as string,
|
||||
automatic_payment_methods: {
|
||||
allow_redirects: 'never',
|
||||
enabled: true,
|
||||
},
|
||||
capture_method: 'manual', // Authorize without capturing
|
||||
confirm: true, // Confirm the PaymentIntent
|
||||
});
|
||||
|
||||
if (paymentIntent.status !== 'requires_capture') {
|
||||
console.error('Cant charge');
|
||||
await stripe.paymentMethods.detach(paymentMethods.data[0].id);
|
||||
await stripe.subscriptions.cancel(event.data.object.id as string);
|
||||
return false;
|
||||
}
|
||||
|
||||
await stripe.paymentIntents.cancel(paymentIntent.id as string);
|
||||
return true;
|
||||
} catch (err) {
|
||||
try {
|
||||
await stripe.paymentMethods.detach(paymentMethods.data[0].id);
|
||||
await stripe.subscriptions.cancel(event.data.object.id as string);
|
||||
} catch (err) {/*dont do anything*/}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async createSubscription(event: Stripe.CustomerSubscriptionCreatedEvent) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const {
|
||||
id,
|
||||
uniqueId,
|
||||
billing,
|
||||
period,
|
||||
}: {
|
||||
billing: 'STANDARD' | 'PRO';
|
||||
period: 'MONTHLY' | 'YEARLY';
|
||||
id: string;
|
||||
uniqueId: string;
|
||||
} = event.data.object.metadata;
|
||||
|
||||
const check = await this.checkValidCard(event);
|
||||
if (!check) {
|
||||
return { ok: false };
|
||||
}
|
||||
|
||||
return this._subscriptionService.createOrUpdateSubscription(
|
||||
id,
|
||||
uniqueId,
|
||||
event.data.object.customer as string,
|
||||
pricing[billing].channel!,
|
||||
billing,
|
||||
|
|
@ -61,20 +136,26 @@ export class StripeService {
|
|||
event.data.object.cancel_at
|
||||
);
|
||||
}
|
||||
updateSubscription(event: Stripe.CustomerSubscriptionUpdatedEvent) {
|
||||
async updateSubscription(event: Stripe.CustomerSubscriptionUpdatedEvent) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const {
|
||||
id,
|
||||
uniqueId,
|
||||
billing,
|
||||
period,
|
||||
}: {
|
||||
billing: 'STANDARD' | 'PRO';
|
||||
period: 'MONTHLY' | 'YEARLY';
|
||||
id: string;
|
||||
uniqueId: string;
|
||||
} = event.data.object.metadata;
|
||||
|
||||
const check = await this.checkValidCard(event);
|
||||
if (!check) {
|
||||
return { ok: false };
|
||||
}
|
||||
|
||||
return this._subscriptionService.createOrUpdateSubscription(
|
||||
id,
|
||||
uniqueId,
|
||||
event.data.object.customer as string,
|
||||
pricing[billing].channel!,
|
||||
billing,
|
||||
|
|
@ -213,6 +294,15 @@ export class StripeService {
|
|||
}
|
||||
}
|
||||
|
||||
async getCustomerSubscriptions(organizationId: string) {
|
||||
const org = (await this._organizationService.getOrgById(organizationId))!;
|
||||
const customer = org.paymentId;
|
||||
return stripe.subscriptions.list({
|
||||
customer: customer!,
|
||||
status: 'all',
|
||||
});
|
||||
}
|
||||
|
||||
async setToCancel(organizationId: string) {
|
||||
const id = makeId(10);
|
||||
const org = await this._organizationService.getOrgById(organizationId);
|
||||
|
|
@ -223,7 +313,7 @@ export class StripeService {
|
|||
customer,
|
||||
status: 'all',
|
||||
})
|
||||
).data,
|
||||
).data.filter((f) => f.status !== 'canceled'),
|
||||
};
|
||||
|
||||
const { cancel_at } = await stripe.subscriptions.update(
|
||||
|
|
@ -265,10 +355,13 @@ export class StripeService {
|
|||
}
|
||||
|
||||
private async createCheckoutSession(
|
||||
ud: string,
|
||||
uniqueId: string,
|
||||
customer: string,
|
||||
body: BillingSubscribeDto,
|
||||
price: string
|
||||
price: string,
|
||||
userId: string,
|
||||
allowTrial: boolean
|
||||
) {
|
||||
const isUtm = body.utm ? `&utm_source=${body.utm}` : '';
|
||||
const { url } = await stripe.checkout.sessions.create({
|
||||
|
|
@ -279,18 +372,22 @@ export class StripeService {
|
|||
`/launches?onboarding=true&check=${uniqueId}${isUtm}`,
|
||||
mode: 'subscription',
|
||||
subscription_data: {
|
||||
trial_period_days: 7,
|
||||
...(allowTrial ? { trial_period_days: 7 } : {}),
|
||||
metadata: {
|
||||
service: 'gitroom',
|
||||
...body,
|
||||
userId,
|
||||
uniqueId,
|
||||
ud,
|
||||
},
|
||||
},
|
||||
...body.tolt ? {
|
||||
metadata: {
|
||||
tolt_referral: body.tolt,
|
||||
}
|
||||
} : {},
|
||||
...(body.tolt
|
||||
? {
|
||||
metadata: {
|
||||
tolt_referral: body.tolt,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
allow_promotion_codes: true,
|
||||
line_items: [
|
||||
{
|
||||
|
|
@ -359,6 +456,34 @@ export class StripeService {
|
|||
return accountLink.url;
|
||||
}
|
||||
|
||||
async checkSubscription(organizationId: string, subscriptionId: string) {
|
||||
const orgValue = await this._subscriptionService.checkSubscription(
|
||||
organizationId,
|
||||
subscriptionId
|
||||
);
|
||||
|
||||
if (orgValue) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
const getCustomerSubscriptions = await this.getCustomerSubscriptions(
|
||||
organizationId
|
||||
);
|
||||
if (getCustomerSubscriptions.data.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (
|
||||
getCustomerSubscriptions.data.find(
|
||||
(p) => p.metadata.uniqueId === subscriptionId
|
||||
)?.canceled_at
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
async payAccountStepOne(
|
||||
userId: string,
|
||||
organization: Organization,
|
||||
|
|
@ -416,7 +541,13 @@ export class StripeService {
|
|||
return { url };
|
||||
}
|
||||
|
||||
async subscribe(organizationId: string, body: BillingSubscribeDto) {
|
||||
async subscribe(
|
||||
uniqueId: string,
|
||||
organizationId: string,
|
||||
userId: string,
|
||||
body: BillingSubscribeDto,
|
||||
allowTrial: boolean
|
||||
) {
|
||||
const id = makeId(10);
|
||||
const priceData = pricing[body.billing];
|
||||
const org = await this._organizationService.getOrgById(organizationId);
|
||||
|
|
@ -465,6 +596,21 @@ export class StripeService {
|
|||
},
|
||||
}));
|
||||
|
||||
const getCurrentSubscriptions =
|
||||
await this._subscriptionService.getSubscription(organizationId);
|
||||
|
||||
if (!getCurrentSubscriptions) {
|
||||
return this.createCheckoutSession(
|
||||
uniqueId,
|
||||
id,
|
||||
customer,
|
||||
body,
|
||||
findPrice!.id,
|
||||
userId,
|
||||
allowTrial
|
||||
);
|
||||
}
|
||||
|
||||
const currentUserSubscription = {
|
||||
data: (
|
||||
await stripe.subscriptions.list({
|
||||
|
|
@ -474,17 +620,15 @@ export class StripeService {
|
|||
).data.filter((f) => f.status === 'active' || f.status === 'trialing'),
|
||||
};
|
||||
|
||||
if (!currentUserSubscription.data.length) {
|
||||
return this.createCheckoutSession(id, customer, body, findPrice!.id);
|
||||
}
|
||||
|
||||
try {
|
||||
await stripe.subscriptions.update(currentUserSubscription.data[0].id, {
|
||||
cancel_at_period_end: false,
|
||||
metadata: {
|
||||
service: 'gitroom',
|
||||
...body,
|
||||
userId,
|
||||
id,
|
||||
ud: uniqueId,
|
||||
},
|
||||
proration_behavior: 'always_invoice',
|
||||
items: [
|
||||
|
|
@ -505,6 +649,23 @@ export class StripeService {
|
|||
}
|
||||
}
|
||||
|
||||
async paymentSucceeded(event: Stripe.InvoicePaymentSucceededEvent) {
|
||||
// get subscription from payment
|
||||
const subscription = await stripe.subscriptions.retrieve(
|
||||
event.data.object.subscription as string
|
||||
);
|
||||
|
||||
const { userId, ud } = subscription.metadata;
|
||||
const user = await this._userService.getUserById(userId);
|
||||
if (user && user.ip && user.agent) {
|
||||
this._trackService.track(ud, user.ip, user.agent, TrackEnum.Purchase, {
|
||||
value: event.data.object.amount_paid / 100,
|
||||
});
|
||||
}
|
||||
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
async updateOrder(event: Stripe.CheckoutSessionCompletedEvent) {
|
||||
if (event?.data?.object?.metadata?.type !== 'marketplace') {
|
||||
return { ok: true };
|
||||
|
|
|
|||
|
|
@ -0,0 +1,85 @@
|
|||
import { TrackEnum } from '@gitroom/nestjs-libraries/user/track.enum';
|
||||
import { User } from '@prisma/client';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import {
|
||||
ServerEvent,
|
||||
EventRequest,
|
||||
UserData,
|
||||
CustomData,
|
||||
FacebookAdsApi,
|
||||
} from 'facebook-nodejs-business-sdk';
|
||||
import { createHash } from 'crypto';
|
||||
|
||||
const access_token = process.env.FACEBOOK_PIXEL_ACCESS_TOKEN!;
|
||||
const pixel_id = process.env.NEXT_PUBLIC_FACEBOOK_PIXEL!;
|
||||
|
||||
if (access_token && pixel_id) {
|
||||
FacebookAdsApi.init(access_token || '');
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class TrackService {
|
||||
private hashValue(value: string) {
|
||||
return createHash('sha256').update(value).digest('hex');
|
||||
}
|
||||
track(
|
||||
uniqueId: string,
|
||||
ip: string,
|
||||
agent: string,
|
||||
tt: TrackEnum,
|
||||
additional: Record<string, any>,
|
||||
fbclid?: string,
|
||||
user?: User
|
||||
) {
|
||||
if (!access_token || !pixel_id) {
|
||||
return;
|
||||
}
|
||||
// @ts-ignore
|
||||
const current_timestamp = Math.floor(new Date() / 1000);
|
||||
|
||||
const userData = new UserData();
|
||||
if (ip || user?.ip) {
|
||||
userData.setClientIpAddress(ip || user?.ip || '');
|
||||
}
|
||||
|
||||
if (agent || user?.agent) {
|
||||
userData.setClientUserAgent(agent || user?.agent || '');
|
||||
}
|
||||
if (fbclid) {
|
||||
userData.setFbc(fbclid);
|
||||
}
|
||||
|
||||
if (user && user.email) {
|
||||
userData.setEmail(this.hashValue(user.email));
|
||||
}
|
||||
|
||||
let customData = null;
|
||||
if (additional?.value) {
|
||||
customData = new CustomData();
|
||||
customData.setValue(additional.value).setCurrency('USD');
|
||||
}
|
||||
|
||||
const serverEvent = new ServerEvent()
|
||||
.setEventName(TrackEnum[tt])
|
||||
.setEventTime(current_timestamp)
|
||||
.setActionSource('website');
|
||||
|
||||
if (user && user.id) {
|
||||
serverEvent.setEventId(uniqueId || user.id);
|
||||
}
|
||||
|
||||
if (userData) {
|
||||
serverEvent.setUserData(userData);
|
||||
}
|
||||
if (customData) {
|
||||
serverEvent.setCustomData(customData);
|
||||
}
|
||||
|
||||
const eventsData = [serverEvent];
|
||||
const eventRequest = new EventRequest(access_token, pixel_id).setEvents(
|
||||
eventsData
|
||||
);
|
||||
|
||||
return eventRequest.execute();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
export enum TrackEnum {
|
||||
ViewContent = 0,
|
||||
CompleteRegistration = 1,
|
||||
InitiateCheckout = 2,
|
||||
StartTrial = 3,
|
||||
Purchase = 4,
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
|
||||
|
||||
export const UserAgent = createParamDecorator(
|
||||
(data: unknown, ctx: ExecutionContext): string => {
|
||||
const request = ctx.switchToHttp().getRequest();
|
||||
return request.headers['user-agent'];
|
||||
},
|
||||
);
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
import { TrackEnum } from '@gitroom/nestjs-libraries/user/track.enum';
|
||||
import { useUser } from '@gitroom/frontend/components/layout/user.context';
|
||||
import { useFetch } from '@gitroom/helpers/utils/custom.fetch';
|
||||
import { useCallback } from 'react';
|
||||
import { useVariables } from '@gitroom/react/helpers/variable.context';
|
||||
|
||||
export const useTrack = () => {
|
||||
const user = useUser();
|
||||
const fetch = useFetch();
|
||||
const { facebookPixel } = useVariables();
|
||||
|
||||
return useCallback(
|
||||
async (track: TrackEnum, additional?: Record<string, any>) => {
|
||||
if (!facebookPixel) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const { track: uq } = await (
|
||||
await fetch(user ? `/user/t` : `/public/t`, {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
tt: track,
|
||||
...(additional ? { additional } : {}),
|
||||
}),
|
||||
})
|
||||
).json();
|
||||
|
||||
if (window.fbq) {
|
||||
// @ts-ignore
|
||||
window.fbq('track', TrackEnum[track], additional, {eventID: uq});
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
[user]
|
||||
);
|
||||
};
|
||||
|
|
@ -11,6 +11,7 @@ interface VariableContextInterface {
|
|||
backendUrl: string;
|
||||
discordUrl: string;
|
||||
uploadDirectory: string;
|
||||
facebookPixel: string;
|
||||
tolt: string;
|
||||
}
|
||||
const VariableContext = createContext({
|
||||
|
|
@ -22,6 +23,7 @@ const VariableContext = createContext({
|
|||
backendUrl: '',
|
||||
discordUrl: '',
|
||||
uploadDirectory: '',
|
||||
facebookPixel: '',
|
||||
tolt: '',
|
||||
} as VariableContextInterface);
|
||||
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@
|
|||
"@aws-sdk/client-s3": "^3.410.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.410.0",
|
||||
"@casl/ability": "^6.5.0",
|
||||
"@copilotkit/react-core": "^1.4.6",
|
||||
"@copilotkit/react-textarea": "^1.4.6",
|
||||
"@copilotkit/react-ui": "^1.4.6",
|
||||
"@copilotkit/runtime": "^1.4.6",
|
||||
"@copilotkit/react-core": "^1.4.7",
|
||||
"@copilotkit/react-textarea": "^1.4.7",
|
||||
"@copilotkit/react-ui": "^1.4.7",
|
||||
"@copilotkit/runtime": "^1.4.7",
|
||||
"@hookform/resolvers": "^3.3.4",
|
||||
"@mantine/core": "^5.10.5",
|
||||
"@mantine/dates": "^5.10.5",
|
||||
|
|
@ -46,6 +46,7 @@
|
|||
"@sweetalert2/theme-dark": "^5.0.16",
|
||||
"@types/bcrypt": "^5.0.2",
|
||||
"@types/concat-stream": "^2.0.3",
|
||||
"@types/facebook-nodejs-business-sdk": "^20.0.2",
|
||||
"@types/jsonwebtoken": "^9.0.5",
|
||||
"@types/lodash": "^4.14.202",
|
||||
"@types/md5": "^2.3.5",
|
||||
|
|
@ -83,6 +84,7 @@
|
|||
"copy-to-clipboard": "^3.3.3",
|
||||
"crypto-hash": "^3.0.0",
|
||||
"dayjs": "^1.11.10",
|
||||
"facebook-nodejs-business-sdk": "^21.0.5",
|
||||
"google-auth-library": "^9.11.0",
|
||||
"googleapis": "^137.1.0",
|
||||
"ioredis": "^5.3.2",
|
||||
|
|
@ -94,6 +96,7 @@
|
|||
"mime-types": "^2.1.35",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"nestjs-command": "^3.1.4",
|
||||
"nestjs-real-ip": "^3.0.1",
|
||||
"next": "^14.2.14",
|
||||
"next-plausible": "^3.12.0",
|
||||
"nodemailer": "^6.9.15",
|
||||
|
|
@ -3107,12 +3110,12 @@
|
|||
"integrity": "sha512-ZykIcDTVv5UNmKWSTLAs3VukO6NDJkkSKxrgUTDPBkAlORVT3H9n5DbRjRl8xIotklscHdbLIa0b9+y3mQq73g=="
|
||||
},
|
||||
"node_modules/@copilotkit/react-core": {
|
||||
"version": "1.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@copilotkit/react-core/-/react-core-1.4.6.tgz",
|
||||
"integrity": "sha512-HPWy7Xf55bfoGoI1eQgx9ijB8BRVCreolc3Gex0Pi8drmyGxjRW0XPUg79qzIejI/ZmU8ynY+dA8swmnw7LJzw==",
|
||||
"version": "1.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@copilotkit/react-core/-/react-core-1.4.7.tgz",
|
||||
"integrity": "sha512-6NxmqxlJzZDxC7L9jilA+tpCe9a2NimcttP/frrLr1ly+8mW2mpCRlz7GtvwMgbC2DX/52QL+siEk49+MQJ3vg==",
|
||||
"dependencies": {
|
||||
"@copilotkit/runtime-client-gql": "1.4.6",
|
||||
"@copilotkit/shared": "1.4.6",
|
||||
"@copilotkit/runtime-client-gql": "1.4.7",
|
||||
"@copilotkit/shared": "1.4.7",
|
||||
"@scarf/scarf": "^1.3.0",
|
||||
"untruncate-json": "^0.0.1"
|
||||
},
|
||||
|
|
@ -3122,13 +3125,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@copilotkit/react-textarea": {
|
||||
"version": "1.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@copilotkit/react-textarea/-/react-textarea-1.4.6.tgz",
|
||||
"integrity": "sha512-kcSowWAVcw8qJW2D23GtjVecTFa2DCt5r+oDcA/UM701fNR/OipakjpFlpQrGiiK6yV3nitvyJLbwbCCXnHiMg==",
|
||||
"version": "1.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@copilotkit/react-textarea/-/react-textarea-1.4.7.tgz",
|
||||
"integrity": "sha512-Le6XJu/AuTdk5JCKRcwuVdxEmBJ3fupvNL4CA6kgFqhhfhBhJrELUfinzdYlJJZu7xEKFAM0ywJPYCjtR/Blqg==",
|
||||
"dependencies": {
|
||||
"@copilotkit/react-core": "1.4.6",
|
||||
"@copilotkit/runtime-client-gql": "1.4.6",
|
||||
"@copilotkit/shared": "1.4.6",
|
||||
"@copilotkit/react-core": "1.4.7",
|
||||
"@copilotkit/runtime-client-gql": "1.4.7",
|
||||
"@copilotkit/shared": "1.4.7",
|
||||
"@emotion/css": "^11.11.2",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
|
|
@ -3162,13 +3165,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@copilotkit/react-ui": {
|
||||
"version": "1.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@copilotkit/react-ui/-/react-ui-1.4.6.tgz",
|
||||
"integrity": "sha512-Aoff4mME2DXXfWOtJXPaR+F+JYBGz6qt1eIUnrLQ4kWjhU+IBZ1sssb4hSKG7Q2kV/Ld6FTjYcSHQOWYPs7Mdw==",
|
||||
"version": "1.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@copilotkit/react-ui/-/react-ui-1.4.7.tgz",
|
||||
"integrity": "sha512-qtzY/eJ1tY865JPr53M5FI/n6sfIYGYXH2URRjfJ5tfQfiii/qLkrDZ5erh5QT9zJJJSr+XNnUuSGtOZPpehJQ==",
|
||||
"dependencies": {
|
||||
"@copilotkit/react-core": "1.4.6",
|
||||
"@copilotkit/runtime-client-gql": "1.4.6",
|
||||
"@copilotkit/shared": "1.4.6",
|
||||
"@copilotkit/react-core": "1.4.7",
|
||||
"@copilotkit/runtime-client-gql": "1.4.7",
|
||||
"@copilotkit/shared": "1.4.7",
|
||||
"@headlessui/react": "^2.1.3",
|
||||
"react-markdown": "^8.0.7",
|
||||
"react-syntax-highlighter": "^15.5.0",
|
||||
|
|
@ -3240,12 +3243,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@copilotkit/runtime": {
|
||||
"version": "1.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@copilotkit/runtime/-/runtime-1.4.6.tgz",
|
||||
"integrity": "sha512-G3XYKK/ZsyEvh8vzdkpEgErhf2tr8tKrIIe6oof9lFNXiQbmQ0c/E0/jOn67jfgL6v6CjXS15RTX8nag6G3IcA==",
|
||||
"version": "1.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@copilotkit/runtime/-/runtime-1.4.7.tgz",
|
||||
"integrity": "sha512-/JyCHknaXHsaRjIiDds7fTvJaHUE6opRO0yZmJr9pi0SSuWOV9cBKY8NcAzm3r0Y0bzrjWShTxKs2+wrMa8Y5g==",
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.27.3",
|
||||
"@copilotkit/shared": "1.4.6",
|
||||
"@copilotkit/shared": "1.4.7",
|
||||
"@graphql-yoga/plugin-defer-stream": "^3.3.1",
|
||||
"@langchain/community": "^0.0.53",
|
||||
"@langchain/core": "^0.3.13",
|
||||
|
|
@ -3270,11 +3273,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@copilotkit/runtime-client-gql": {
|
||||
"version": "1.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@copilotkit/runtime-client-gql/-/runtime-client-gql-1.4.6.tgz",
|
||||
"integrity": "sha512-gEP+V4YrSb6X9ViL5CUkkbBrugAbNzuqZJ/TNfekUcbkA3XDtpz71M5LR0Z1tlX3l8T5zDNq/xGKSadJqrvt7A==",
|
||||
"version": "1.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@copilotkit/runtime-client-gql/-/runtime-client-gql-1.4.7.tgz",
|
||||
"integrity": "sha512-gZml12gXHd5FsTH296KiQ/0cW8GaONxOUfgHvlcFp6HfxzjKaEjdyYcfnzEw7auZwXQimme7cup++95RS8xETw==",
|
||||
"dependencies": {
|
||||
"@copilotkit/shared": "1.4.6",
|
||||
"@copilotkit/shared": "1.4.7",
|
||||
"@urql/core": "^5.0.3",
|
||||
"untruncate-json": "^0.0.1",
|
||||
"urql": "^4.1.0"
|
||||
|
|
@ -4150,9 +4153,9 @@
|
|||
"peer": true
|
||||
},
|
||||
"node_modules/@copilotkit/shared": {
|
||||
"version": "1.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@copilotkit/shared/-/shared-1.4.6.tgz",
|
||||
"integrity": "sha512-40CckHiJGX3cwJ6dVl1DXCVQxysYdKPS4snQkygZ4HqrhLZ3oznaqwKgU5CCezuh7IIjS91J8M/hpKTbC7fPmA==",
|
||||
"version": "1.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@copilotkit/shared/-/shared-1.4.7.tgz",
|
||||
"integrity": "sha512-WYLQ2lfBlqzMDDguky2uibnN/QZA1rL8T8J4KNSkugw4obJTSG1ESf2KraBkbQZvw7UIutOVrxY/iDTv2OFcMw==",
|
||||
"dependencies": {
|
||||
"@segment/analytics-node": "^2.1.2",
|
||||
"chalk": "4.1.2",
|
||||
|
|
@ -4893,11 +4896,11 @@
|
|||
"integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig=="
|
||||
},
|
||||
"node_modules/@graphql-tools/executor": {
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/@graphql-tools/executor/-/executor-1.3.8.tgz",
|
||||
"integrity": "sha512-tiZ8/PaQ+wkdZeCSyHa7vOUqCJndnpnN5ilUpi5UwsFrFFyN71sr4NJeib7Txf1VdufJNB4ed/0yFd39O0L3AQ==",
|
||||
"version": "1.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@graphql-tools/executor/-/executor-1.3.9.tgz",
|
||||
"integrity": "sha512-BpBWW6WMgIQeLQIFHJ9HHPaCX9mzEn4sv2qP0mb4acW4z45HB4znRFf3vxq83jMOOhWjrvY0vE2UjMVYnsvvSQ==",
|
||||
"dependencies": {
|
||||
"@graphql-tools/utils": "^10.6.3",
|
||||
"@graphql-tools/utils": "^10.6.4",
|
||||
"@graphql-typed-document-node/core": "^3.2.0",
|
||||
"@repeaterjs/repeater": "^3.0.4",
|
||||
"@whatwg-node/disposablestack": "^0.0.5",
|
||||
|
|
@ -4912,11 +4915,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@graphql-tools/merge": {
|
||||
"version": "9.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-9.0.13.tgz",
|
||||
"integrity": "sha512-OSEOaFOjdkAwR6umRHrTrKjYANbh/0OBb1W8B21dxu8XPaOeoCuShDGXY6ZpragiO8Ke0qFXZGwJGg8ZbDPfvQ==",
|
||||
"version": "9.0.14",
|
||||
"resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-9.0.14.tgz",
|
||||
"integrity": "sha512-MO7VXnm3ShpdG51hs4hYsLyu+8o/tSLjNYQmLmR4rkHoFi3kQCDu2r8B4IVwd+Ve39cechj0NyCmMsg+mRvwDQ==",
|
||||
"dependencies": {
|
||||
"@graphql-tools/utils": "^10.6.3",
|
||||
"@graphql-tools/utils": "^10.6.4",
|
||||
"tslib": "^2.4.0"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -4927,12 +4930,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@graphql-tools/schema": {
|
||||
"version": "10.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-10.0.12.tgz",
|
||||
"integrity": "sha512-ukIZBdD4jI94ren5GK6nnHe+YvDVOfoI8cz50pdE1+FYf9NSFUu7HJXmIBHGIIWFbE5lz4qb5MfUeuBkffs3lw==",
|
||||
"version": "10.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-10.0.13.tgz",
|
||||
"integrity": "sha512-1gvTTuSKej9bR5O2SP9dCKSHaQkVmg9fWU0Aia34HMsAZl2bzosUfXjwBu3ze8MWqb+gRVjdhukDpGA5ZC+5nA==",
|
||||
"dependencies": {
|
||||
"@graphql-tools/merge": "^9.0.13",
|
||||
"@graphql-tools/utils": "^10.6.3",
|
||||
"@graphql-tools/merge": "^9.0.14",
|
||||
"@graphql-tools/utils": "^10.6.4",
|
||||
"tslib": "^2.4.0",
|
||||
"value-or-promise": "^1.0.12"
|
||||
},
|
||||
|
|
@ -4944,9 +4947,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@graphql-tools/utils": {
|
||||
"version": "10.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.6.3.tgz",
|
||||
"integrity": "sha512-hEaQTGyQUG3DJqCaIsiu4M+jUgWUf+h6kDwC8MtGElwkL1HWi+qX2qyynw8h9WoV7STmmHDSwkk2ET1IC3nRPw==",
|
||||
"version": "10.6.4",
|
||||
"resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.6.4.tgz",
|
||||
"integrity": "sha512-itCgjwVxbO+3uI/K73G9heedG8KelNFzgn368rUhPjTrkJX6NyLQwT5EMq/A8tvazMXyJYdtnN5nD+tT4DUpbQ==",
|
||||
"dependencies": {
|
||||
"@graphql-typed-document-node/core": "^3.1.1",
|
||||
"cross-inspect": "1.0.1",
|
||||
|
|
@ -4980,9 +4983,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@graphql-yoga/plugin-defer-stream": {
|
||||
"version": "3.10.5",
|
||||
"resolved": "https://registry.npmjs.org/@graphql-yoga/plugin-defer-stream/-/plugin-defer-stream-3.10.5.tgz",
|
||||
"integrity": "sha512-hdywCAeVUvONn2c1gHoyuCUesobgnk0fXVGKvxINxRAN5cXwL5sHKU8yXPiPI5JgH1q790cyGXUnqA1pZpp53w==",
|
||||
"version": "3.10.6",
|
||||
"resolved": "https://registry.npmjs.org/@graphql-yoga/plugin-defer-stream/-/plugin-defer-stream-3.10.6.tgz",
|
||||
"integrity": "sha512-i7R2rsBLWm+vjtqJ9CGA84EtRAgVXICKbQmEamT69TzVyej0FGhJx9K9kDyyA13mYfg+qEgXnIvfnf6gUjvryA==",
|
||||
"dependencies": {
|
||||
"@graphql-tools/utils": "^10.6.1"
|
||||
},
|
||||
|
|
@ -4991,7 +4994,7 @@
|
|||
},
|
||||
"peerDependencies": {
|
||||
"graphql": "^15.2.0 || ^16.0.0",
|
||||
"graphql-yoga": "^5.10.5"
|
||||
"graphql-yoga": "^5.10.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@graphql-yoga/subscription": {
|
||||
|
|
@ -10423,6 +10426,11 @@
|
|||
"node": ">=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@supercharge/request-ip": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@supercharge/request-ip/-/request-ip-1.2.0.tgz",
|
||||
"integrity": "sha512-wlt6JW69MHqLY2M6Sm/jVyCojNRKq2CBvwH0Hbx24SFhDQQGkgEjeKxVutDxHSyrWixFaOSLXC27euzxijhyMQ=="
|
||||
},
|
||||
"node_modules/@svgr/babel-plugin-add-jsx-attribute": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz",
|
||||
|
|
@ -11325,6 +11333,11 @@
|
|||
"@types/send": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/facebook-nodejs-business-sdk": {
|
||||
"version": "20.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/facebook-nodejs-business-sdk/-/facebook-nodejs-business-sdk-20.0.2.tgz",
|
||||
"integrity": "sha512-simgmhDaOO0cC2USu1WUixiOq/RJly0DiP+oIJnh3ANzcNVT0BLtpjl4M4HsbPaTNMZ1JT952W/hJ9N7UztYyQ=="
|
||||
},
|
||||
"node_modules/@types/graceful-fs": {
|
||||
"version": "4.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
|
||||
|
|
@ -14898,9 +14911,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/bullmq": {
|
||||
"version": "5.34.1",
|
||||
"resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.34.1.tgz",
|
||||
"integrity": "sha512-AIyfpWJlfDJczA479uoYAo6CUPdrUP85Jo6B379X9iht8FjxVLSP91ZpDjLJKL3//LGfZmonhpOWKO4ZoPysFA==",
|
||||
"version": "5.34.2",
|
||||
"resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.34.2.tgz",
|
||||
"integrity": "sha512-eUzeCswrKbQDE1WY8h4ZTBtynOzCU5qx9felFdYOmIJrsy0warDahHKUiCZ6dUCs6ZxYMGtcaciIMcAf1L54yw==",
|
||||
"dependencies": {
|
||||
"cron-parser": "^4.6.0",
|
||||
"ioredis": "^5.4.1",
|
||||
|
|
@ -16641,6 +16654,15 @@
|
|||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
|
||||
},
|
||||
"node_modules/currency-codes": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/currency-codes/-/currency-codes-1.5.1.tgz",
|
||||
"integrity": "sha512-hqy8vtlIYKzO6pe2TE0V4/riZALIc7nhtE9cvxk5FDRCvfGplgzUvpTmZlMsyO+NeK5U41j+sQXJOo8l8v9kdg==",
|
||||
"dependencies": {
|
||||
"first-match": "~0.0.1",
|
||||
"nub": "~0.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/damerau-levenshtein": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
|
||||
|
|
@ -18946,6 +18968,18 @@
|
|||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||
},
|
||||
"node_modules/facebook-nodejs-business-sdk": {
|
||||
"version": "21.0.5",
|
||||
"resolved": "https://registry.npmjs.org/facebook-nodejs-business-sdk/-/facebook-nodejs-business-sdk-21.0.5.tgz",
|
||||
"integrity": "sha512-WRmYZQtQYZWFHCrzlIqgj0tSRCDslSWd9IT2ccs8ah+Mr4QxC3uZrP7tVAkqYJshINKL1v30swlGDCGK5VmMTg==",
|
||||
"dependencies": {
|
||||
"axios": "^1.4.0",
|
||||
"currency-codes": "^1.5.1",
|
||||
"iso-3166-1": "^2.1.1",
|
||||
"js-sha256": "^0.9.0",
|
||||
"mixwith": "~0.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-copy": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.2.tgz",
|
||||
|
|
@ -19371,6 +19405,11 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/first-match": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/first-match/-/first-match-0.0.1.tgz",
|
||||
"integrity": "sha512-VvKbnaxrC0polTFDC+teKPTdl2mn6B/KUW+WB3C9RzKDeNwbzfLdnUz3FxC+tnjvus6bI0jWrWicQyVIPdS37A=="
|
||||
},
|
||||
"node_modules/flat": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
|
||||
|
|
@ -20286,9 +20325,9 @@
|
|||
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="
|
||||
},
|
||||
"node_modules/graphql": {
|
||||
"version": "16.9.0",
|
||||
"resolved": "https://registry.npmjs.org/graphql/-/graphql-16.9.0.tgz",
|
||||
"integrity": "sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==",
|
||||
"version": "16.10.0",
|
||||
"resolved": "https://registry.npmjs.org/graphql/-/graphql-16.10.0.tgz",
|
||||
"integrity": "sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ==",
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
|
||||
}
|
||||
|
|
@ -20319,9 +20358,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/graphql-yoga": {
|
||||
"version": "5.10.5",
|
||||
"resolved": "https://registry.npmjs.org/graphql-yoga/-/graphql-yoga-5.10.5.tgz",
|
||||
"integrity": "sha512-W5bpXHRb6S3H3Th8poDm6b+ZMRjke8hsy9WVFgRriDTGh0AenIkpJzZT5VgXUD+j1yLCMrvhUNc6MNmgaRExsw==",
|
||||
"version": "5.10.6",
|
||||
"resolved": "https://registry.npmjs.org/graphql-yoga/-/graphql-yoga-5.10.6.tgz",
|
||||
"integrity": "sha512-RqKTNN4ii/pnUhGBuFF3WyNy52AMs5ArTY/lGQUYH/1FQk5t2RgAZE5OxWRgobhmr+cuN066bvgVIlt4mnnRNA==",
|
||||
"dependencies": {
|
||||
"@envelop/core": "^5.0.2",
|
||||
"@graphql-tools/executor": "^1.3.7",
|
||||
|
|
@ -21615,14 +21654,6 @@
|
|||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ioredis": {
|
||||
"version": "5.4.1",
|
||||
"resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.4.1.tgz",
|
||||
|
|
@ -22265,6 +22296,11 @@
|
|||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
|
||||
},
|
||||
"node_modules/iso-3166-1": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/iso-3166-1/-/iso-3166-1-2.1.1.tgz",
|
||||
"integrity": "sha512-RZxXf8cw5Y8LyHZIwIRvKw8sWTIHh2/txBT+ehO0QroesVfnz3JNFFX4i/OC/Yuv2bDIVYrHna5PMvjtpefq5w=="
|
||||
},
|
||||
"node_modules/iso-datestring-validator": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/iso-datestring-validator/-/iso-datestring-validator-2.2.2.tgz",
|
||||
|
|
@ -23491,6 +23527,11 @@
|
|||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/js-sha256": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz",
|
||||
"integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA=="
|
||||
},
|
||||
"node_modules/js-tiktoken": {
|
||||
"version": "1.0.15",
|
||||
"resolved": "https://registry.npmjs.org/js-tiktoken/-/js-tiktoken-1.0.15.tgz",
|
||||
|
|
@ -28273,6 +28314,11 @@
|
|||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"node_modules/mixwith": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/mixwith/-/mixwith-0.1.1.tgz",
|
||||
"integrity": "sha512-DQsf/liljH/9e+94jR+xfK8vlKceeKdOM9H9UEXLwGuvEEpO6debNtJ9yt1ZKzPKPrwqGxzMdu0BR1fnQb6i4A=="
|
||||
},
|
||||
"node_modules/mkdirp": {
|
||||
"version": "0.5.6",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
|
||||
|
|
@ -28623,6 +28669,17 @@
|
|||
"yargs": "^16.0.0 || ^17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nestjs-real-ip": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/nestjs-real-ip/-/nestjs-real-ip-3.0.1.tgz",
|
||||
"integrity": "sha512-vsBlvXBWXg+GorIoXmTasNaJZyeBpTypgnrq1jk9xOEL7FGv9ZFBafyhllliNbSuCDpwxeC7Sxc6hBk8onPXUg==",
|
||||
"dependencies": {
|
||||
"@supercharge/request-ip": "^1.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nestjs/common": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/next": {
|
||||
"version": "14.2.20",
|
||||
"resolved": "https://registry.npmjs.org/next/-/next-14.2.20.tgz",
|
||||
|
|
@ -28987,6 +29044,14 @@
|
|||
"url": "https://github.com/fb55/nth-check?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/nub": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/nub/-/nub-0.0.0.tgz",
|
||||
"integrity": "sha512-dK0Ss9C34R/vV0FfYJXuqDAqHlaW9fvWVufq9MmGF2umCuDbd5GRfRD9fpi/LiM0l4ZXf8IBB+RYmZExqCrf0w==",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/num-sort": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/num-sort/-/num-sort-2.1.0.tgz",
|
||||
|
|
@ -31048,9 +31113,9 @@
|
|||
"integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg=="
|
||||
},
|
||||
"node_modules/rambda": {
|
||||
"version": "9.4.0",
|
||||
"resolved": "https://registry.npmjs.org/rambda/-/rambda-9.4.0.tgz",
|
||||
"integrity": "sha512-B7y7goUd+g0hNl5ODGUejNNERQL5gD8uANJ5Y5aHly8v0jKesFlwIe7prPfuJxttDpe3otQzHJ4NXMpTmL9ELA=="
|
||||
"version": "9.4.1",
|
||||
"resolved": "https://registry.npmjs.org/rambda/-/rambda-9.4.1.tgz",
|
||||
"integrity": "sha512-awZe9AzmPI8XqizJz+NlaRbAdjhWKvuIaPikqRH6r41/ui9UTUQY5jTVdgQwnVrv1HnSMB6IBAAnNYs8HoVvZg=="
|
||||
},
|
||||
"node_modules/randombytes": {
|
||||
"version": "2.1.0",
|
||||
|
|
@ -31377,19 +31442,19 @@
|
|||
}
|
||||
},
|
||||
"node_modules/react-remove-scroll-bar": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz",
|
||||
"integrity": "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==",
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz",
|
||||
"integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==",
|
||||
"dependencies": {
|
||||
"react-style-singleton": "^2.2.1",
|
||||
"react-style-singleton": "^2.2.2",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
"@types/react": "*",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
|
|
@ -31418,20 +31483,19 @@
|
|||
"integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
|
||||
},
|
||||
"node_modules/react-style-singleton": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz",
|
||||
"integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",
|
||||
"integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==",
|
||||
"dependencies": {
|
||||
"get-nonce": "^1.0.0",
|
||||
"invariant": "^2.2.4",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
"@types/react": "*",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
|
|
@ -35292,20 +35356,20 @@
|
|||
}
|
||||
},
|
||||
"node_modules/tldts": {
|
||||
"version": "6.1.67",
|
||||
"resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.67.tgz",
|
||||
"integrity": "sha512-714VbegxoZ9WF5/IsVCy9rWXKUpPkJq87ebWLXQzNawce96l5oRrRf2eHzB4pT2g/4HQU1dYbu+sdXClYxlDKQ==",
|
||||
"version": "6.1.68",
|
||||
"resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.68.tgz",
|
||||
"integrity": "sha512-JKF17jROiYkjJPT73hUTEiTp2OBCf+kAlB+1novk8i6Q6dWjHsgEjw9VLiipV4KTJavazXhY1QUXyQFSem2T7w==",
|
||||
"dependencies": {
|
||||
"tldts-core": "^6.1.67"
|
||||
"tldts-core": "^6.1.68"
|
||||
},
|
||||
"bin": {
|
||||
"tldts": "bin/cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/tldts-core": {
|
||||
"version": "6.1.67",
|
||||
"resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.67.tgz",
|
||||
"integrity": "sha512-12K5O4m3uUW6YM5v45Z7wc6NTSmAYj4Tq3de7eXghZkp879IlfPJrUWeWFwu1FS94U5t2vwETgJ1asu8UGNKVQ=="
|
||||
"version": "6.1.68",
|
||||
"resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.68.tgz",
|
||||
"integrity": "sha512-85TdlS/DLW/gVdf2oyyzqp3ocS30WxjaL4la85EArl9cHUR/nizifKAJPziWewSZjDZS71U517/i6ciUeqtB5Q=="
|
||||
},
|
||||
"node_modules/tmp": {
|
||||
"version": "0.2.3",
|
||||
|
|
@ -36399,9 +36463,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/use-sidecar": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz",
|
||||
"integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==",
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz",
|
||||
"integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==",
|
||||
"dependencies": {
|
||||
"detect-node-es": "^1.1.0",
|
||||
"tslib": "^2.0.0"
|
||||
|
|
@ -36410,8 +36474,8 @@
|
|||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
"@types/react": "*",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
|
|
|
|||
11
package.json
11
package.json
|
|
@ -36,10 +36,10 @@
|
|||
"@aws-sdk/client-s3": "^3.410.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.410.0",
|
||||
"@casl/ability": "^6.5.0",
|
||||
"@copilotkit/react-core": "^1.4.6",
|
||||
"@copilotkit/react-textarea": "^1.4.6",
|
||||
"@copilotkit/react-ui": "^1.4.6",
|
||||
"@copilotkit/runtime": "^1.4.6",
|
||||
"@copilotkit/react-core": "^1.4.7",
|
||||
"@copilotkit/react-textarea": "^1.4.7",
|
||||
"@copilotkit/react-ui": "^1.4.7",
|
||||
"@copilotkit/runtime": "^1.4.7",
|
||||
"@hookform/resolvers": "^3.3.4",
|
||||
"@mantine/core": "^5.10.5",
|
||||
"@mantine/dates": "^5.10.5",
|
||||
|
|
@ -68,6 +68,7 @@
|
|||
"@sweetalert2/theme-dark": "^5.0.16",
|
||||
"@types/bcrypt": "^5.0.2",
|
||||
"@types/concat-stream": "^2.0.3",
|
||||
"@types/facebook-nodejs-business-sdk": "^20.0.2",
|
||||
"@types/jsonwebtoken": "^9.0.5",
|
||||
"@types/lodash": "^4.14.202",
|
||||
"@types/md5": "^2.3.5",
|
||||
|
|
@ -105,6 +106,7 @@
|
|||
"copy-to-clipboard": "^3.3.3",
|
||||
"crypto-hash": "^3.0.0",
|
||||
"dayjs": "^1.11.10",
|
||||
"facebook-nodejs-business-sdk": "^21.0.5",
|
||||
"google-auth-library": "^9.11.0",
|
||||
"googleapis": "^137.1.0",
|
||||
"ioredis": "^5.3.2",
|
||||
|
|
@ -116,6 +118,7 @@
|
|||
"mime-types": "^2.1.35",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"nestjs-command": "^3.1.4",
|
||||
"nestjs-real-ip": "^3.0.1",
|
||||
"next": "^14.2.14",
|
||||
"next-plausible": "^3.12.0",
|
||||
"nodemailer": "^6.9.15",
|
||||
|
|
|
|||
Loading…
Reference in New Issue