feat: comments, preview, duplicate
This commit is contained in:
commit
62da0cd98e
|
|
@ -14,7 +14,6 @@ import { SettingsController } from '@gitroom/backend/api/routes/settings.control
|
|||
import { PostsController } from '@gitroom/backend/api/routes/posts.controller';
|
||||
import { MediaController } from '@gitroom/backend/api/routes/media.controller';
|
||||
import { UploadModule } from '@gitroom/nestjs-libraries/upload/upload.module';
|
||||
import { CommentsController } from '@gitroom/backend/api/routes/comments.controller';
|
||||
import { BillingController } from '@gitroom/backend/api/routes/billing.controller';
|
||||
import { NotificationsController } from '@gitroom/backend/api/routes/notifications.controller';
|
||||
import { MarketplaceController } from '@gitroom/backend/api/routes/marketplace.controller';
|
||||
|
|
@ -35,7 +34,6 @@ const authenticatedController = [
|
|||
SettingsController,
|
||||
PostsController,
|
||||
MediaController,
|
||||
CommentsController,
|
||||
BillingController,
|
||||
NotificationsController,
|
||||
MarketplaceController,
|
||||
|
|
|
|||
|
|
@ -1,82 +0,0 @@
|
|||
import {Body, Controller, Delete, Get, Param, Post, Put} from '@nestjs/common';
|
||||
import { CommentsService } from '@gitroom/nestjs-libraries/database/prisma/comments/comments.service';
|
||||
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request';
|
||||
import { Organization, User } from '@prisma/client';
|
||||
import { GetUserFromRequest } from '@gitroom/nestjs-libraries/user/user.from.request';
|
||||
import { AddCommentDto } from '@gitroom/nestjs-libraries/dtos/comments/add.comment.dto';
|
||||
import {ApiTags} from "@nestjs/swagger";
|
||||
|
||||
@ApiTags('Comments')
|
||||
@Controller('/comments')
|
||||
export class CommentsController {
|
||||
constructor(private _commentsService: CommentsService) {}
|
||||
|
||||
@Post('/')
|
||||
addComment(
|
||||
@GetOrgFromRequest() org: Organization,
|
||||
@GetUserFromRequest() user: User,
|
||||
@Body() addCommentDto: AddCommentDto
|
||||
) {
|
||||
return this._commentsService.addAComment(
|
||||
org.id,
|
||||
user.id,
|
||||
addCommentDto.content,
|
||||
addCommentDto.date
|
||||
);
|
||||
}
|
||||
|
||||
@Post('/:id')
|
||||
addCommentTocComment(
|
||||
@GetOrgFromRequest() org: Organization,
|
||||
@GetUserFromRequest() user: User,
|
||||
@Body() addCommentDto: AddCommentDto,
|
||||
@Param('id') id: string
|
||||
) {
|
||||
return this._commentsService.addACommentToComment(
|
||||
org.id,
|
||||
user.id,
|
||||
id,
|
||||
addCommentDto.content,
|
||||
addCommentDto.date
|
||||
);
|
||||
}
|
||||
|
||||
@Put('/:id')
|
||||
editComment(
|
||||
@GetOrgFromRequest() org: Organization,
|
||||
@GetUserFromRequest() user: User,
|
||||
@Body() addCommentDto: AddCommentDto,
|
||||
@Param('id') id: string
|
||||
) {
|
||||
return this._commentsService.updateAComment(
|
||||
org.id,
|
||||
user.id,
|
||||
id,
|
||||
addCommentDto.content
|
||||
);
|
||||
}
|
||||
|
||||
@Delete('/:id')
|
||||
deleteComment(
|
||||
@GetOrgFromRequest() org: Organization,
|
||||
@GetUserFromRequest() user: User,
|
||||
@Param('id') id: string
|
||||
) {
|
||||
return this._commentsService.deleteAComment(
|
||||
org.id,
|
||||
user.id,
|
||||
id,
|
||||
);
|
||||
}
|
||||
|
||||
@Get('/:date')
|
||||
loadAllCommentsAndSubCommentsForADate(
|
||||
@GetOrgFromRequest() org: Organization,
|
||||
@Param('date') date: string
|
||||
) {
|
||||
return this._commentsService.loadAllCommentsAndSubCommentsForADate(
|
||||
org.id,
|
||||
date
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@ import { GeneratorDto } from '@gitroom/nestjs-libraries/dtos/generator/generator
|
|||
import { CreateGeneratedPostsDto } from '@gitroom/nestjs-libraries/dtos/generator/create.generated.posts.dto';
|
||||
import { AgentGraphService } from '@gitroom/nestjs-libraries/agent/agent.graph.service';
|
||||
import { Response } from 'express';
|
||||
import { GetUserFromRequest } from '@gitroom/nestjs-libraries/user/user.from.request';
|
||||
|
||||
@ApiTags('Posts')
|
||||
@Controller('/posts')
|
||||
|
|
@ -45,10 +46,14 @@ export class PostsController {
|
|||
return this._messagesService.getMarketplaceAvailableOffers(org.id, id);
|
||||
}
|
||||
|
||||
@Post('/posts/generate-image')
|
||||
@CheckPolicies([AuthorizationActions.Create, Sections.POSTS_PER_MONTH])
|
||||
generateImage(@Body() body: { text: string; type: string }) {
|
||||
|
||||
@Post('/:id/comments')
|
||||
async createComment(
|
||||
@GetOrgFromRequest() org: Organization,
|
||||
@GetUserFromRequest() user: User,
|
||||
@Param('id') id: string,
|
||||
@Body() body: { comment: string }
|
||||
) {
|
||||
return this._postsService.createComment(org.id, user.id, id, body.comment);
|
||||
}
|
||||
|
||||
@Get('/')
|
||||
|
|
@ -71,6 +76,13 @@ export class PostsController {
|
|||
};
|
||||
}
|
||||
|
||||
@Get('/find-slot')
|
||||
async findSlot(
|
||||
@GetOrgFromRequest() org: Organization,
|
||||
) {
|
||||
return {date: await this._postsService.findFreeDateTime(org.id)}
|
||||
}
|
||||
|
||||
@Get('/predict-trending')
|
||||
predictTrending() {
|
||||
return this._starsService.predictTrending();
|
||||
|
|
|
|||
|
|
@ -1,16 +1,14 @@
|
|||
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 { GetUserFromRequest } from '@gitroom/nestjs-libraries/user/user.from.request';
|
||||
import { User } from '@prisma/client';
|
||||
import { makeId } from '@gitroom/nestjs-libraries/services/make.is';
|
||||
import { getCookieUrlFromDomain } from '@gitroom/helpers/subdomain/subdomain.management';
|
||||
import { AgentGraphService } from '@gitroom/nestjs-libraries/agent/agent.graph.service';
|
||||
import { AgentGraphInsertService } from '@gitroom/nestjs-libraries/agent/agent.graph.insert.service';
|
||||
|
||||
@ApiTags('Public')
|
||||
|
|
@ -19,7 +17,8 @@ export class PublicController {
|
|||
constructor(
|
||||
private _agenciesService: AgenciesService,
|
||||
private _trackService: TrackService,
|
||||
private _agentGraphInsertService: AgentGraphInsertService
|
||||
private _agentGraphInsertService: AgentGraphInsertService,
|
||||
private _postsService: PostsService
|
||||
) {}
|
||||
@Post('/agent')
|
||||
async createAgent(@Body() body: { text: string; apiKey: string }) {
|
||||
|
|
@ -53,6 +52,31 @@ export class PublicController {
|
|||
return this._agenciesService.getCount();
|
||||
}
|
||||
|
||||
@Get(`/posts/:id`)
|
||||
async getPreview(@Param('id') id: string) {
|
||||
return (await this._postsService.getPostsRecursively(id, true)).map(
|
||||
({ childrenPost, ...p }) => ({
|
||||
...p,
|
||||
...(p.integration
|
||||
? {
|
||||
integration: {
|
||||
id: p.integration.id,
|
||||
name: p.integration.name,
|
||||
picture: p.integration.picture,
|
||||
providerIdentifier: p.integration.providerIdentifier,
|
||||
profile: p.integration.profile,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@Get(`/posts/:id/comments`)
|
||||
async getComments(@Param('id') postId: string) {
|
||||
return { comments: await this._postsService.getComments(postId) };
|
||||
}
|
||||
|
||||
@Post('/t')
|
||||
async trackEvent(
|
||||
@Res() res: Response,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
import { ReactNode } from 'react';
|
||||
import { PreviewWrapper } from '@gitroom/frontend/components/preview/preview.wrapper';
|
||||
|
||||
export default async function AppLayout({ children }: { children: ReactNode }) {
|
||||
return <PreviewWrapper>{children}</PreviewWrapper>;
|
||||
}
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
import { internalFetch } from '@gitroom/helpers/utils/internal.fetch';
|
||||
|
||||
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 Link from 'next/link';
|
||||
import { CommentsComponents } from '@gitroom/frontend/components/preview/comments.components';
|
||||
import dayjs from 'dayjs';
|
||||
import utc from 'dayjs/plugin/utc';
|
||||
import { VideoOrImage } from '@gitroom/react/helpers/video.or.image';
|
||||
import { CopyClient } from '@gitroom/frontend/components/preview/copy.client';
|
||||
|
||||
dayjs.extend(utc);
|
||||
export const metadata: Metadata = {
|
||||
title: `${isGeneralServerSide() ? 'Postiz' : 'Gitroom'} Preview`,
|
||||
description: '',
|
||||
};
|
||||
|
||||
export default async function Auth({
|
||||
params: { id },
|
||||
searchParams,
|
||||
}: {
|
||||
params: { id: string };
|
||||
searchParams?: { share?: string };
|
||||
}) {
|
||||
const post = await (await internalFetch(`/public/posts/${id}`)).json();
|
||||
|
||||
if (!post.length) {
|
||||
return (
|
||||
<div className="text-white fixed left-0 top-0 w-full h-full flex justify-center items-center text-[20px]">
|
||||
Post not found
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="mx-auto w-full max-w-[1346px] py-3 text-white">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="min-w-[55px]">
|
||||
<Link
|
||||
href="/"
|
||||
className="text-2xl flex items-center justify-center gap-[10px] text-textColor order-1"
|
||||
>
|
||||
<div className="max-w-[55px]">
|
||||
<Image
|
||||
src={'/postiz.svg'}
|
||||
width={55}
|
||||
height={55}
|
||||
alt="Logo"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<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>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-sm text-gray-400 flex items-center gap-[20px]">
|
||||
{!!searchParams?.share && (
|
||||
<div>
|
||||
<CopyClient />
|
||||
</div>
|
||||
)}
|
||||
<div className="flex-1">
|
||||
Publication Date:{' '}
|
||||
{dayjs
|
||||
.utc(post[0].createdAt)
|
||||
.local()
|
||||
.format('MMMM D, YYYY h:mm A')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col lg:flex-row text-white w-full max-w-[1346px] mx-auto">
|
||||
<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 bg-third border border-tableBorder"
|
||||
>
|
||||
<div className="flex space-x-3">
|
||||
<div>
|
||||
<div className="flex shrink-0 rounded-full h-30 w-30 relative">
|
||||
<div className="w-[50px] h-[50px] z-[20]">
|
||||
<img
|
||||
className="w-full h-full relative z-[20] bg-black aspect-square rounded-full border-tableBorder"
|
||||
alt={post[0].integration.name}
|
||||
src={post[0].integration.picture}
|
||||
/>
|
||||
</div>
|
||||
<div className="absolute -right-[5px] -bottom-[5px] w-[30px] h-[30px] z-[20]">
|
||||
<img
|
||||
className="w-full h-full bg-black aspect-square rounded-full border-tableBorder"
|
||||
alt={post[0].integration.providerIdentifier}
|
||||
src={`/icons/platforms/${post[0].integration.providerIdentifier}.png`}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 space-y-1">
|
||||
<div className="flex items-center space-x-2">
|
||||
<h2 className="text-sm font-semibold">
|
||||
{post[0].integration.name}
|
||||
</h2>
|
||||
<span className="text-sm text-gray-500">
|
||||
@{post[0].integration.profile}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-col gap-[20px]">
|
||||
<div
|
||||
className="text-sm whitespace-pre-wrap"
|
||||
dangerouslySetInnerHTML={{ __html: p.content }}
|
||||
/>
|
||||
<div className="flex w-full gap-[10px]">
|
||||
{JSON.parse(p?.image || '[]').map((p: any) => (
|
||||
<div
|
||||
key={p.name}
|
||||
className="flex-1 rounded-[10px] overflow-hidden"
|
||||
>
|
||||
<VideoOrImage src={p.path} autoplay={true} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full lg:w-96 lg:flex-shrink-0">
|
||||
<div className="p-4 pt-0">
|
||||
<CommentsComponents postId={id} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -38,8 +38,25 @@ export const AddProviderButton: FC<{ update?: () => void }> = (props) => {
|
|||
const { update } = props;
|
||||
const add = useAddProvider(update);
|
||||
return (
|
||||
<button className="text-white p-[8px] rounded-md bg-forth" onClick={add}>
|
||||
Add Channel
|
||||
<button
|
||||
className="text-white p-[8px] rounded-md bg-forth flex gap-[5px]"
|
||||
onClick={add}
|
||||
>
|
||||
<div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 32 32"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M7 26C7 26.2652 6.89464 26.5196 6.70711 26.7071C6.51957 26.8946 6.26522 27 6 27C5.73478 27 5.48043 26.8946 5.29289 26.7071C5.10536 26.5196 5 26.2652 5 26C5 25.7348 4.89464 25.4804 4.70711 25.2929C4.51957 25.1054 4.26522 25 4 25C3.73478 25 3.48043 24.8946 3.29289 24.7071C3.10536 24.5196 3 24.2652 3 24C3 23.7348 3.10536 23.4804 3.29289 23.2929C3.48043 23.1054 3.73478 23 4 23C4.79565 23 5.55871 23.3161 6.12132 23.8787C6.68393 24.4413 7 25.2044 7 26ZM4 19C3.73478 19 3.48043 19.1054 3.29289 19.2929C3.10536 19.4804 3 19.7348 3 20C3 20.2652 3.10536 20.5196 3.29289 20.7071C3.48043 20.8946 3.73478 21 4 21C5.32608 21 6.59785 21.5268 7.53553 22.4645C8.47322 23.4021 9 24.6739 9 26C9 26.2652 9.10536 26.5196 9.29289 26.7071C9.48043 26.8946 9.73478 27 10 27C10.2652 27 10.5196 26.8946 10.7071 26.7071C10.8946 26.5196 11 26.2652 11 26C10.998 24.1441 10.2599 22.3648 8.94755 21.0524C7.63523 19.7401 5.85591 19.002 4 19ZM4 15C3.73478 15 3.48043 15.1054 3.29289 15.2929C3.10536 15.4804 3 15.7348 3 16C3 16.2652 3.10536 16.5196 3.29289 16.7071C3.48043 16.8946 3.73478 17 4 17C6.38614 17.0026 8.67378 17.9517 10.361 19.639C12.0483 21.3262 12.9974 23.6139 13 26C13 26.2652 13.1054 26.5196 13.2929 26.7071C13.4804 26.8946 13.7348 27 14 27C14.2652 27 14.5196 26.8946 14.7071 26.7071C14.8946 26.5196 15 26.2652 15 26C14.9967 23.0836 13.8367 20.2877 11.7745 18.2255C9.71234 16.1633 6.91637 15.0033 4 15ZM27 5H5C4.46957 5 3.96086 5.21071 3.58579 5.58579C3.21071 5.96086 3 6.46957 3 7V12C3 12.2652 3.10536 12.5196 3.29289 12.7071C3.48043 12.8946 3.73478 13 4 13C7.4467 13.0036 10.7512 14.3744 13.1884 16.8116C15.6256 19.2488 16.9964 22.5533 17 26C17 26.2652 17.1054 26.5196 17.2929 26.7071C17.4804 26.8946 17.7348 27 18 27H27C27.5304 27 28.0391 26.7893 28.4142 26.4142C28.7893 26.0391 29 25.5304 29 25V7C29 6.46957 28.7893 5.96086 28.4142 5.58579C28.0391 5.21071 27.5304 5 27 5Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div className="flex-1 text-left">Add Channel</div>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -311,12 +311,15 @@ export const CalendarColumn: FC<{
|
|||
return getDate.startOf('hour').isBefore(dayjs().startOf('hour'));
|
||||
}, [getDate, num]);
|
||||
|
||||
const { start, stop } = useInterval(useCallback(() => {
|
||||
if (isBeforeNow) {
|
||||
return ;
|
||||
}
|
||||
setNum(num + 1);
|
||||
}, [isBeforeNow]), random(120000, 150000));
|
||||
const { start, stop } = useInterval(
|
||||
useCallback(() => {
|
||||
if (isBeforeNow) {
|
||||
return;
|
||||
}
|
||||
setNum(num + 1);
|
||||
}, [isBeforeNow]),
|
||||
random(120000, 150000)
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
start();
|
||||
|
|
@ -401,12 +404,15 @@ export const CalendarColumn: FC<{
|
|||
);
|
||||
|
||||
const editPost = useCallback(
|
||||
(post: Post & { integration: Integration }) => async () => {
|
||||
(post: Post & { integration: Integration }, isDuplicate?: boolean) => async () => {
|
||||
if (user?.orgId === post.submittedForOrganizationId) {
|
||||
return previewPublication(post);
|
||||
}
|
||||
const data = await (await fetch(`/posts/${post.id}`)).json();
|
||||
const publishDate = dayjs.utc(data.posts[0].publishDate).local();
|
||||
const date = !isDuplicate ? null : (await (await fetch('/posts/find-slot')).json()).date;
|
||||
const publishDate = dayjs.utc(date || data.posts[0].publishDate).local();
|
||||
|
||||
const ExistingData = !isDuplicate ? ExistingDataContextProvider : Fragment;
|
||||
|
||||
modal.openModal({
|
||||
closeOnClickOutside: false,
|
||||
|
|
@ -416,18 +422,19 @@ export const CalendarColumn: FC<{
|
|||
modal: 'w-[100%] max-w-[1400px] bg-transparent text-textColor',
|
||||
},
|
||||
children: (
|
||||
<ExistingDataContextProvider value={data}>
|
||||
<ExistingData value={data}>
|
||||
<AddEditModal
|
||||
{...isDuplicate ? {onlyValues: data.posts} : {}}
|
||||
allIntegrations={integrations.map((p) => ({ ...p }))}
|
||||
reopenModal={editPost(post)}
|
||||
mutate={reloadCalendarView}
|
||||
integrations={integrations
|
||||
integrations={isDuplicate ? integrations : integrations
|
||||
.slice(0)
|
||||
.filter((f) => f.id === data.integration)
|
||||
.map((p) => ({ ...p, picture: data.integrationPicture }))}
|
||||
date={publishDate}
|
||||
/>
|
||||
</ExistingDataContextProvider>
|
||||
</ExistingData>
|
||||
),
|
||||
size: '80%',
|
||||
title: ``,
|
||||
|
|
@ -484,7 +491,7 @@ export const CalendarColumn: FC<{
|
|||
}
|
||||
: {})}
|
||||
className={clsx(
|
||||
'flex-col text-[12px] pointer w-full overflow-hidden overflow-x-auto flex scrollbar scrollbar-thumb-tableBorder scrollbar-track-secondary',
|
||||
'flex-col text-[12px] pointer w-full flex scrollbar scrollbar-thumb-tableBorder scrollbar-track-secondary',
|
||||
isBeforeNow ? 'bg-customColor23 flex-1' : 'cursor-pointer',
|
||||
isBeforeNow && postList.length === 0 && 'col-calendar',
|
||||
canBeTrending && 'bg-customColor24'
|
||||
|
|
@ -497,13 +504,14 @@ export const CalendarColumn: FC<{
|
|||
'text-textColor p-[2.5px] relative flex flex-col justify-center items-center'
|
||||
)}
|
||||
>
|
||||
<div className="relative w-full flex flex-col items-center p-[2.5px] h-[56px]">
|
||||
<div className="relative w-full flex flex-col items-center p-[2.5px] h-[66px]">
|
||||
<CalendarItem
|
||||
display={display as 'day' | 'week' | 'month'}
|
||||
isBeforeNow={isBeforeNow}
|
||||
date={getDate}
|
||||
state={post.state}
|
||||
editPost={editPost(post)}
|
||||
editPost={editPost(post, false)}
|
||||
duplicatePost={editPost(post, true)}
|
||||
post={post}
|
||||
integrations={integrations}
|
||||
/>
|
||||
|
|
@ -588,12 +596,18 @@ const CalendarItem: FC<{
|
|||
date: dayjs.Dayjs;
|
||||
isBeforeNow: boolean;
|
||||
editPost: () => void;
|
||||
duplicatePost: () => void;
|
||||
integrations: Integrations[];
|
||||
state: State;
|
||||
display: 'day' | 'week' | 'month';
|
||||
post: Post & { integration: Integration };
|
||||
}> = (props) => {
|
||||
const { editPost, post, date, isBeforeNow, state, display } = props;
|
||||
const { editPost, duplicatePost, post, date, isBeforeNow, state, display } = props;
|
||||
|
||||
const preview = useCallback(() => {
|
||||
window.open(`/p/` + post.id + '?share=true', '_blank');
|
||||
}, [post]);
|
||||
|
||||
const [{ opacity }, dragRef] = useDrag(
|
||||
() => ({
|
||||
type: 'post',
|
||||
|
|
@ -608,33 +622,41 @@ const CalendarItem: FC<{
|
|||
<div
|
||||
// @ts-ignore
|
||||
ref={dragRef}
|
||||
onClick={editPost}
|
||||
className={clsx(
|
||||
'gap-[5px] w-full flex h-full flex-1 rounded-[10px] border border-seventh px-[5px] p-[2.5px]',
|
||||
'relative',
|
||||
(state === 'DRAFT' || isBeforeNow) && '!grayscale'
|
||||
)}
|
||||
className={clsx('w-full flex h-full flex-1 flex-col group', 'relative')}
|
||||
style={{ opacity }}
|
||||
>
|
||||
<div className="bg-forth text-[11px] h-[15px] w-full rounded-tr-[10px] rounded-tl-[10px] flex justify-center gap-[10px] px-[5px]">
|
||||
<div className="hidden group-hover:block hover:underline cursor-pointer" onClick={duplicatePost}>Duplicate</div>
|
||||
<div className="hidden group-hover:block hover:underline cursor-pointer" onClick={preview}>Preview</div>
|
||||
</div>
|
||||
<div
|
||||
onClick={editPost}
|
||||
className={clsx(
|
||||
'relative min-w-[20px] h-[20px]',
|
||||
display === 'day' ? 'h-[40px]' : 'h-[20px]'
|
||||
'gap-[5px] w-full flex h-full flex-1 rounded-br-[10px] rounded-bl-[10px] border border-seventh px-[5px] p-[2.5px]',
|
||||
'relative',
|
||||
(isBeforeNow) && '!grayscale'
|
||||
)}
|
||||
>
|
||||
<img
|
||||
className="w-[20px] h-[20px] rounded-full"
|
||||
src={post.integration.picture!}
|
||||
/>
|
||||
<img
|
||||
className="w-[12px] h-[12px] rounded-full absolute z-10 top-[10px] right-0 border border-fifth"
|
||||
src={`/icons/platforms/${post.integration?.providerIdentifier}.png`}
|
||||
/>
|
||||
</div>
|
||||
<div className="whitespace-nowrap line-clamp-2">
|
||||
<div className="text-left">{state === 'DRAFT' ? 'Draft: ' : ''}</div>
|
||||
<div className="w-full overflow-hidden overflow-ellipsis text-left">
|
||||
{removeMd(post.content).replace(/\n/g, ' ')}
|
||||
<div
|
||||
className={clsx(
|
||||
'relative min-w-[20px] h-[20px]',
|
||||
display === 'day' ? 'h-[40px]' : 'h-[20px]'
|
||||
)}
|
||||
>
|
||||
<img
|
||||
className="w-[20px] h-[20px] rounded-full"
|
||||
src={post.integration.picture!}
|
||||
/>
|
||||
<img
|
||||
className="w-[12px] h-[12px] rounded-full absolute z-10 top-[10px] right-0 border border-fifth"
|
||||
src={`/icons/platforms/${post.integration?.providerIdentifier}.png`}
|
||||
/>
|
||||
</div>
|
||||
<div className="whitespace-nowrap line-clamp-2">
|
||||
<div className="text-left">{state === 'DRAFT' ? 'Draft: ' : ''}</div>
|
||||
<div className="w-full overflow-hidden overflow-ellipsis text-left">
|
||||
{removeMd(post.content).replace(/\n/g, ' ')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -320,7 +320,7 @@ export const GeneratorComponent = () => {
|
|||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
Generate Posts
|
||||
<div className="flex-1 text-left">Generate Posts</div>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import { useDrag, useDrop } from 'react-dnd';
|
|||
import { DNDProvider } from '@gitroom/frontend/components/launches/helpers/dnd.provider';
|
||||
import { GeneratorComponent } from './generator/generator';
|
||||
import { useVariables } from '@gitroom/react/helpers/variable.context';
|
||||
import { NewPost } from '@gitroom/frontend/components/launches/new.post';
|
||||
|
||||
interface MenuComponentInterface {
|
||||
refreshChannel: (
|
||||
|
|
@ -120,14 +121,22 @@ export const MenuGroupComponent: FC<
|
|||
</div>
|
||||
)}
|
||||
{!!group.name && (
|
||||
<div className="flex items-center gap-[5px] cursor-pointer" onClick={changeOpenClose}>
|
||||
<div
|
||||
className="flex items-center gap-[5px] cursor-pointer"
|
||||
onClick={changeOpenClose}
|
||||
>
|
||||
<div>
|
||||
<OpenClose isOpen={isOpen} />
|
||||
</div>
|
||||
<div>{group.name}</div>
|
||||
</div>
|
||||
)}
|
||||
<div className={clsx("gap-[16px] flex flex-col relative", !isOpen && 'hidden')}>
|
||||
<div
|
||||
className={clsx(
|
||||
'gap-[16px] flex flex-col relative',
|
||||
!isOpen && 'hidden'
|
||||
)}
|
||||
>
|
||||
{group.values.map((integration) => (
|
||||
<MenuComponent
|
||||
key={integration.id}
|
||||
|
|
@ -427,10 +436,13 @@ export const LaunchesComponent = () => {
|
|||
/>
|
||||
))}
|
||||
</div>
|
||||
<AddProviderButton update={() => update(true)} />
|
||||
{sortedIntegrations?.length > 0 &&
|
||||
user?.tier?.ai &&
|
||||
billingEnabled && <GeneratorComponent />}
|
||||
<div className="flex flex-col gap-[10px]">
|
||||
<AddProviderButton update={() => update(true)} />
|
||||
{sortedIntegrations?.length > 0 && <NewPost />}
|
||||
{sortedIntegrations?.length > 0 &&
|
||||
user?.tier?.ai &&
|
||||
billingEnabled && <GeneratorComponent />}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 flex flex-col gap-[14px]">
|
||||
<Filters />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import { AddEditModal } from '@gitroom/frontend/components/launches/add.edit.model';
|
||||
import { useModals } from '@mantine/modals';
|
||||
import dayjs from 'dayjs';
|
||||
import { useCalendar } from '@gitroom/frontend/components/launches/calendar.context';
|
||||
import { useFetch } from '@gitroom/helpers/utils/custom.fetch';
|
||||
|
||||
export const NewPost = () => {
|
||||
const fetch = useFetch();
|
||||
const modal = useModals();
|
||||
const { integrations, reloadCalendarView } = useCalendar();
|
||||
|
||||
const createAPost = useCallback(async () => {
|
||||
const date = (await (await fetch('/posts/find-slot')).json()).date;
|
||||
modal.openModal({
|
||||
closeOnClickOutside: false,
|
||||
closeOnEscape: false,
|
||||
withCloseButton: false,
|
||||
classNames: {
|
||||
modal: 'w-[100%] max-w-[1400px] bg-transparent text-textColor',
|
||||
},
|
||||
children: (
|
||||
<AddEditModal
|
||||
allIntegrations={integrations.map((p) => ({ ...p }))}
|
||||
reopenModal={createAPost}
|
||||
mutate={reloadCalendarView}
|
||||
integrations={integrations}
|
||||
date={dayjs.utc(date).local()}
|
||||
/>
|
||||
),
|
||||
size: '80%',
|
||||
title: ``,
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={createAPost}
|
||||
className="p-[8px] rounded-md bg-green-900 flex justify-center items-center gap-[5px] outline-none text-white"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 32 32"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M21 4H11C9.14409 4.00199 7.36477 4.74012 6.05245 6.05245C4.74012 7.36477 4.00199 9.14409 4 11V21C4.00199 22.8559 4.74012 24.6352 6.05245 25.9476C7.36477 27.2599 9.14409 27.998 11 28H17C17.1075 27.9999 17.2142 27.9826 17.3162 27.9487C20.595 26.855 26.855 20.595 27.9487 17.3162C27.9826 17.2142 27.9999 17.1075 28 17V11C27.998 9.14409 27.2599 7.36477 25.9476 6.05245C24.6352 4.74012 22.8559 4.00199 21 4ZM17 25.9275V22C17 20.6739 17.5268 19.4021 18.4645 18.4645C19.4021 17.5268 20.6739 17 22 17H25.9275C24.77 19.6938 19.6938 24.77 17 25.9275Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
<div className="flex-1 text-left">Create New Post</div>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
|
@ -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');
|
||||
|
|
|
|||
|
|
@ -70,167 +70,162 @@ export const LayoutSettings = ({ children }: { children: ReactNode }) => {
|
|||
credentials="include"
|
||||
runtimeUrl={backendUrl + '/copilot/chat'}
|
||||
>
|
||||
<ContextWrapper user={user}>
|
||||
<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>
|
||||
<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 />
|
||||
<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 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>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M16.2806 9.21937C16.3504 9.28903 16.4057 9.37175 16.4434 9.46279C16.4812 9.55384 16.5006 9.65144 16.5006 9.75C16.5006 9.84856 16.4812 9.94616 16.4434 10.0372C16.4057 10.1283 16.3504 10.211 16.2806 10.2806L11.0306 15.5306C10.961 15.6004 10.8783 15.6557 10.7872 15.6934C10.6962 15.7312 10.5986 15.7506 10.5 15.7506C10.4014 15.7506 10.3038 15.7312 10.2128 15.6934C10.1218 15.6557 10.039 15.6004 9.96938 15.5306L7.71938 13.2806C7.57865 13.1399 7.49959 12.949 7.49959 12.75C7.49959 12.551 7.57865 12.3601 7.71938 12.2194C7.86011 12.0786 8.05098 11.9996 8.25 11.9996C8.44903 11.9996 8.6399 12.0786 8.78063 12.2194L10.5 13.9397L15.2194 9.21937C15.289 9.14964 15.3718 9.09432 15.4628 9.05658C15.5538 9.01884 15.6514 8.99941 15.75 8.99941C15.8486 8.99941 15.9462 9.01884 16.0372 9.05658C16.1283 9.09432 16.211 9.14964 16.2806 9.21937ZM21.75 12C21.75 13.9284 21.1782 15.8134 20.1068 17.4168C19.0355 19.0202 17.5127 20.2699 15.7312 21.0078C13.9496 21.7458 11.9892 21.9389 10.0979 21.5627C8.20656 21.1865 6.46928 20.2579 5.10571 18.8943C3.74215 17.5307 2.81355 15.7934 2.43735 13.9021C2.06114 12.0108 2.25422 10.0504 2.99218 8.26884C3.73013 6.48726 4.97982 4.96451 6.58319 3.89317C8.18657 2.82183 10.0716 2.25 12 2.25C14.585 2.25273 17.0634 3.28084 18.8913 5.10872C20.7192 6.93661 21.7473 9.41498 21.75 12ZM20.25 12C20.25 10.3683 19.7661 8.77325 18.8596 7.41655C17.9531 6.05984 16.6646 5.00242 15.1571 4.37799C13.6497 3.75357 11.9909 3.59019 10.3905 3.90852C8.79017 4.22685 7.32016 5.01259 6.16637 6.16637C5.01259 7.32015 4.22685 8.79016 3.90853 10.3905C3.5902 11.9908 3.75358 13.6496 4.378 15.1571C5.00242 16.6646 6.05984 17.9531 7.41655 18.8596C8.77326 19.7661 10.3683 20.25 12 20.25C14.1873 20.2475 16.2843 19.3775 17.8309 17.8309C19.3775 16.2843 20.2475 14.1873 20.25 12Z"
|
||||
fill="#06ff00"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>100% no-risk trial</div>
|
||||
</div>
|
||||
<div className="flex gap-[5px] items-center">
|
||||
<div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M16.2806 9.21937C16.3504 9.28903 16.4057 9.37175 16.4434 9.46279C16.4812 9.55384 16.5006 9.65144 16.5006 9.75C16.5006 9.84856 16.4812 9.94616 16.4434 10.0372C16.4057 10.1283 16.3504 10.211 16.2806 10.2806L11.0306 15.5306C10.961 15.6004 10.8783 15.6557 10.7872 15.6934C10.6962 15.7312 10.5986 15.7506 10.5 15.7506C10.4014 15.7506 10.3038 15.7312 10.2128 15.6934C10.1218 15.6557 10.039 15.6004 9.96938 15.5306L7.71938 13.2806C7.57865 13.1399 7.49959 12.949 7.49959 12.75C7.49959 12.551 7.57865 12.3601 7.71938 12.2194C7.86011 12.0786 8.05098 11.9996 8.25 11.9996C8.44903 11.9996 8.6399 12.0786 8.78063 12.2194L10.5 13.9397L15.2194 9.21937C15.289 9.14964 15.3718 9.09432 15.4628 9.05658C15.5538 9.01884 15.6514 8.99941 15.75 8.99941C15.8486 8.99941 15.9462 9.01884 16.0372 9.05658C16.1283 9.09432 16.211 9.14964 16.2806 9.21937ZM21.75 12C21.75 13.9284 21.1782 15.8134 20.1068 17.4168C19.0355 19.0202 17.5127 20.2699 15.7312 21.0078C13.9496 21.7458 11.9892 21.9389 10.0979 21.5627C8.20656 21.1865 6.46928 20.2579 5.10571 18.8943C3.74215 17.5307 2.81355 15.7934 2.43735 13.9021C2.06114 12.0108 2.25422 10.0504 2.99218 8.26884C3.73013 6.48726 4.97982 4.96451 6.58319 3.89317C8.18657 2.82183 10.0716 2.25 12 2.25C14.585 2.25273 17.0634 3.28084 18.8913 5.10872C20.7192 6.93661 21.7473 9.41498 21.75 12ZM20.25 12C20.25 10.3683 19.7661 8.77325 18.8596 7.41655C17.9531 6.05984 16.6646 5.00242 15.1571 4.37799C13.6497 3.75357 11.9909 3.59019 10.3905 3.90852C8.79017 4.22685 7.32016 5.01259 6.16637 6.16637C5.01259 7.32015 4.22685 8.79016 3.90853 10.3905C3.5902 11.9908 3.75358 13.6496 4.378 15.1571C5.00242 16.6646 6.05984 17.9531 7.41655 18.8596C8.77326 19.7661 10.3683 20.25 12 20.25C14.1873 20.2475 16.2843 19.3775 17.8309 17.8309C19.3775 16.2843 20.2475 14.1873 20.25 12Z"
|
||||
fill="#06ff00"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>Pay nothing for the first 7 days</div>
|
||||
</div>
|
||||
<div className="flex gap-[5px] items-center">
|
||||
<div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M16.2806 9.21937C16.3504 9.28903 16.4057 9.37175 16.4434 9.46279C16.4812 9.55384 16.5006 9.65144 16.5006 9.75C16.5006 9.84856 16.4812 9.94616 16.4434 10.0372C16.4057 10.1283 16.3504 10.211 16.2806 10.2806L11.0306 15.5306C10.961 15.6004 10.8783 15.6557 10.7872 15.6934C10.6962 15.7312 10.5986 15.7506 10.5 15.7506C10.4014 15.7506 10.3038 15.7312 10.2128 15.6934C10.1218 15.6557 10.039 15.6004 9.96938 15.5306L7.71938 13.2806C7.57865 13.1399 7.49959 12.949 7.49959 12.75C7.49959 12.551 7.57865 12.3601 7.71938 12.2194C7.86011 12.0786 8.05098 11.9996 8.25 11.9996C8.44903 11.9996 8.6399 12.0786 8.78063 12.2194L10.5 13.9397L15.2194 9.21937C15.289 9.14964 15.3718 9.09432 15.4628 9.05658C15.5538 9.01884 15.6514 8.99941 15.75 8.99941C15.8486 8.99941 15.9462 9.01884 16.0372 9.05658C16.1283 9.09432 16.211 9.14964 16.2806 9.21937ZM21.75 12C21.75 13.9284 21.1782 15.8134 20.1068 17.4168C19.0355 19.0202 17.5127 20.2699 15.7312 21.0078C13.9496 21.7458 11.9892 21.9389 10.0979 21.5627C8.20656 21.1865 6.46928 20.2579 5.10571 18.8943C3.74215 17.5307 2.81355 15.7934 2.43735 13.9021C2.06114 12.0108 2.25422 10.0504 2.99218 8.26884C3.73013 6.48726 4.97982 4.96451 6.58319 3.89317C8.18657 2.82183 10.0716 2.25 12 2.25C14.585 2.25273 17.0634 3.28084 18.8913 5.10872C20.7192 6.93661 21.7473 9.41498 21.75 12ZM20.25 12C20.25 10.3683 19.7661 8.77325 18.8596 7.41655C17.9531 6.05984 16.6646 5.00242 15.1571 4.37799C13.6497 3.75357 11.9909 3.59019 10.3905 3.90852C8.79017 4.22685 7.32016 5.01259 6.16637 6.16637C5.01259 7.32015 4.22685 8.79016 3.90853 10.3905C3.5902 11.9908 3.75358 13.6496 4.378 15.1571C5.00242 16.6646 6.05984 17.9531 7.41655 18.8596C8.77326 19.7661 10.3683 20.25 12 20.25C14.1873 20.2475 16.2843 19.3775 17.8309 17.8309C19.3775 16.2843 20.2475 14.1873 20.25 12Z"
|
||||
fill="#06ff00"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>Cancel anytime, hassle-free</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<BillingComponent />
|
||||
</>
|
||||
<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>
|
||||
) : (
|
||||
<>
|
||||
<Title />
|
||||
<div className="flex flex-1 flex-col">{children}</div>
|
||||
</>
|
||||
'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>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M16.2806 9.21937C16.3504 9.28903 16.4057 9.37175 16.4434 9.46279C16.4812 9.55384 16.5006 9.65144 16.5006 9.75C16.5006 9.84856 16.4812 9.94616 16.4434 10.0372C16.4057 10.1283 16.3504 10.211 16.2806 10.2806L11.0306 15.5306C10.961 15.6004 10.8783 15.6557 10.7872 15.6934C10.6962 15.7312 10.5986 15.7506 10.5 15.7506C10.4014 15.7506 10.3038 15.7312 10.2128 15.6934C10.1218 15.6557 10.039 15.6004 9.96938 15.5306L7.71938 13.2806C7.57865 13.1399 7.49959 12.949 7.49959 12.75C7.49959 12.551 7.57865 12.3601 7.71938 12.2194C7.86011 12.0786 8.05098 11.9996 8.25 11.9996C8.44903 11.9996 8.6399 12.0786 8.78063 12.2194L10.5 13.9397L15.2194 9.21937C15.289 9.14964 15.3718 9.09432 15.4628 9.05658C15.5538 9.01884 15.6514 8.99941 15.75 8.99941C15.8486 8.99941 15.9462 9.01884 16.0372 9.05658C16.1283 9.09432 16.211 9.14964 16.2806 9.21937ZM21.75 12C21.75 13.9284 21.1782 15.8134 20.1068 17.4168C19.0355 19.0202 17.5127 20.2699 15.7312 21.0078C13.9496 21.7458 11.9892 21.9389 10.0979 21.5627C8.20656 21.1865 6.46928 20.2579 5.10571 18.8943C3.74215 17.5307 2.81355 15.7934 2.43735 13.9021C2.06114 12.0108 2.25422 10.0504 2.99218 8.26884C3.73013 6.48726 4.97982 4.96451 6.58319 3.89317C8.18657 2.82183 10.0716 2.25 12 2.25C14.585 2.25273 17.0634 3.28084 18.8913 5.10872C20.7192 6.93661 21.7473 9.41498 21.75 12ZM20.25 12C20.25 10.3683 19.7661 8.77325 18.8596 7.41655C17.9531 6.05984 16.6646 5.00242 15.1571 4.37799C13.6497 3.75357 11.9909 3.59019 10.3905 3.90852C8.79017 4.22685 7.32016 5.01259 6.16637 6.16637C5.01259 7.32015 4.22685 8.79016 3.90853 10.3905C3.5902 11.9908 3.75358 13.6496 4.378 15.1571C5.00242 16.6646 6.05984 17.9531 7.41655 18.8596C8.77326 19.7661 10.3683 20.25 12 20.25C14.1873 20.2475 16.2843 19.3775 17.8309 17.8309C19.3775 16.2843 20.2475 14.1873 20.25 12Z"
|
||||
fill="#06ff00"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>100% no-risk trial</div>
|
||||
</div>
|
||||
<div className="flex gap-[5px] items-center">
|
||||
<div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M16.2806 9.21937C16.3504 9.28903 16.4057 9.37175 16.4434 9.46279C16.4812 9.55384 16.5006 9.65144 16.5006 9.75C16.5006 9.84856 16.4812 9.94616 16.4434 10.0372C16.4057 10.1283 16.3504 10.211 16.2806 10.2806L11.0306 15.5306C10.961 15.6004 10.8783 15.6557 10.7872 15.6934C10.6962 15.7312 10.5986 15.7506 10.5 15.7506C10.4014 15.7506 10.3038 15.7312 10.2128 15.6934C10.1218 15.6557 10.039 15.6004 9.96938 15.5306L7.71938 13.2806C7.57865 13.1399 7.49959 12.949 7.49959 12.75C7.49959 12.551 7.57865 12.3601 7.71938 12.2194C7.86011 12.0786 8.05098 11.9996 8.25 11.9996C8.44903 11.9996 8.6399 12.0786 8.78063 12.2194L10.5 13.9397L15.2194 9.21937C15.289 9.14964 15.3718 9.09432 15.4628 9.05658C15.5538 9.01884 15.6514 8.99941 15.75 8.99941C15.8486 8.99941 15.9462 9.01884 16.0372 9.05658C16.1283 9.09432 16.211 9.14964 16.2806 9.21937ZM21.75 12C21.75 13.9284 21.1782 15.8134 20.1068 17.4168C19.0355 19.0202 17.5127 20.2699 15.7312 21.0078C13.9496 21.7458 11.9892 21.9389 10.0979 21.5627C8.20656 21.1865 6.46928 20.2579 5.10571 18.8943C3.74215 17.5307 2.81355 15.7934 2.43735 13.9021C2.06114 12.0108 2.25422 10.0504 2.99218 8.26884C3.73013 6.48726 4.97982 4.96451 6.58319 3.89317C8.18657 2.82183 10.0716 2.25 12 2.25C14.585 2.25273 17.0634 3.28084 18.8913 5.10872C20.7192 6.93661 21.7473 9.41498 21.75 12ZM20.25 12C20.25 10.3683 19.7661 8.77325 18.8596 7.41655C17.9531 6.05984 16.6646 5.00242 15.1571 4.37799C13.6497 3.75357 11.9909 3.59019 10.3905 3.90852C8.79017 4.22685 7.32016 5.01259 6.16637 6.16637C5.01259 7.32015 4.22685 8.79016 3.90853 10.3905C3.5902 11.9908 3.75358 13.6496 4.378 15.1571C5.00242 16.6646 6.05984 17.9531 7.41655 18.8596C8.77326 19.7661 10.3683 20.25 12 20.25C14.1873 20.2475 16.2843 19.3775 17.8309 17.8309C19.3775 16.2843 20.2475 14.1873 20.25 12Z"
|
||||
fill="#06ff00"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>Pay nothing for the first 7 days</div>
|
||||
</div>
|
||||
<div className="flex gap-[5px] items-center">
|
||||
<div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M16.2806 9.21937C16.3504 9.28903 16.4057 9.37175 16.4434 9.46279C16.4812 9.55384 16.5006 9.65144 16.5006 9.75C16.5006 9.84856 16.4812 9.94616 16.4434 10.0372C16.4057 10.1283 16.3504 10.211 16.2806 10.2806L11.0306 15.5306C10.961 15.6004 10.8783 15.6557 10.7872 15.6934C10.6962 15.7312 10.5986 15.7506 10.5 15.7506C10.4014 15.7506 10.3038 15.7312 10.2128 15.6934C10.1218 15.6557 10.039 15.6004 9.96938 15.5306L7.71938 13.2806C7.57865 13.1399 7.49959 12.949 7.49959 12.75C7.49959 12.551 7.57865 12.3601 7.71938 12.2194C7.86011 12.0786 8.05098 11.9996 8.25 11.9996C8.44903 11.9996 8.6399 12.0786 8.78063 12.2194L10.5 13.9397L15.2194 9.21937C15.289 9.14964 15.3718 9.09432 15.4628 9.05658C15.5538 9.01884 15.6514 8.99941 15.75 8.99941C15.8486 8.99941 15.9462 9.01884 16.0372 9.05658C16.1283 9.09432 16.211 9.14964 16.2806 9.21937ZM21.75 12C21.75 13.9284 21.1782 15.8134 20.1068 17.4168C19.0355 19.0202 17.5127 20.2699 15.7312 21.0078C13.9496 21.7458 11.9892 21.9389 10.0979 21.5627C8.20656 21.1865 6.46928 20.2579 5.10571 18.8943C3.74215 17.5307 2.81355 15.7934 2.43735 13.9021C2.06114 12.0108 2.25422 10.0504 2.99218 8.26884C3.73013 6.48726 4.97982 4.96451 6.58319 3.89317C8.18657 2.82183 10.0716 2.25 12 2.25C14.585 2.25273 17.0634 3.28084 18.8913 5.10872C20.7192 6.93661 21.7473 9.41498 21.75 12ZM20.25 12C20.25 10.3683 19.7661 8.77325 18.8596 7.41655C17.9531 6.05984 16.6646 5.00242 15.1571 4.37799C13.6497 3.75357 11.9909 3.59019 10.3905 3.90852C8.79017 4.22685 7.32016 5.01259 6.16637 6.16637C5.01259 7.32015 4.22685 8.79016 3.90853 10.3905C3.5902 11.9908 3.75358 13.6496 4.378 15.1571C5.00242 16.6646 6.05984 17.9531 7.41655 18.8596C8.77326 19.7661 10.3683 20.25 12 20.25C14.1873 20.2475 16.2843 19.3775 17.8309 17.8309C19.3775 16.2843 20.2475 14.1873 20.25 12Z"
|
||||
fill="#06ff00"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>Cancel anytime, hassle-free</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<BillingComponent />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Title />
|
||||
<div className="flex flex-1 flex-col">{children}</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</MantineWrapper>
|
||||
</ContextWrapper>
|
||||
</div>
|
||||
</MantineWrapper>
|
||||
</CopilotKit>
|
||||
</ContextWrapper>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,111 @@
|
|||
'use client';
|
||||
import { useUser } from '@gitroom/frontend/components/layout/user.context';
|
||||
import { Button } from '@gitroom/react/form/button';
|
||||
import { FC, useCallback, useMemo, useState } from 'react';
|
||||
import { useFetch } from '@gitroom/helpers/utils/custom.fetch';
|
||||
import useSWR from 'swr';
|
||||
import { FieldValues, SubmitHandler, useForm } from 'react-hook-form';
|
||||
|
||||
export const RenderComponents: FC<{ postId: string }> = (props) => {
|
||||
const { postId } = props;
|
||||
const fetch = useFetch();
|
||||
|
||||
const comments = useCallback(async () => {
|
||||
return (await fetch(`/public/posts/${postId}/comments`)).json();
|
||||
}, [postId]);
|
||||
|
||||
const { data, mutate, isLoading } = useSWR('comments', comments);
|
||||
const mapUsers = useMemo(() => {
|
||||
return (data?.comments || []).reduce((all: any, current: any) => {
|
||||
all.users[current.userId] = all.users[current.userId] || all.counter++;
|
||||
return all;
|
||||
}, {users: {}, counter: 1}).users;
|
||||
}, [data]);
|
||||
|
||||
const {handleSubmit, register, setValue} = useForm();
|
||||
const submit: SubmitHandler<FieldValues> = useCallback(async (e) => {
|
||||
setValue('comment', '');
|
||||
await fetch(`/posts/${postId}/comments`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(e),
|
||||
});
|
||||
|
||||
mutate();
|
||||
}, [postId, mutate]);
|
||||
|
||||
|
||||
if (isLoading) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mb-6 flex space-x-3">
|
||||
<form className="flex-1 space-y-2" onSubmit={handleSubmit(submit)}>
|
||||
<textarea
|
||||
{...register('comment', { required: true })}
|
||||
className="flex w-full px-3 py-2 h-[98px] text-sm ring-offset-background placeholder:text-muted-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 min-h-[80px] resize-none text-white bg-third border border-tableBorder placeholder-gray-500 focus:ring-0"
|
||||
placeholder="Add a comment..."
|
||||
defaultValue={''}
|
||||
/>
|
||||
<div className="flex justify-end">
|
||||
<Button type="submit">
|
||||
<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>
|
||||
</form>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
{!!data.comments.length && (
|
||||
<h3 className="text-lg font-semibold">Comments</h3>
|
||||
)}
|
||||
{data.comments.map((comment: any) => (
|
||||
<div
|
||||
key={comment.id}
|
||||
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">User {mapUsers[comment.userId]}</h3>
|
||||
</div>
|
||||
<p className="text-sm text-gray-300">
|
||||
{comment.content}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export const CommentsComponents: FC<{ postId: string }> = (props) => {
|
||||
const user = useUser();
|
||||
const { postId } = props;
|
||||
|
||||
const goToComments = useCallback(() => {
|
||||
window.location.href = `/auth?returnUrl=${window.location.href}`;
|
||||
}, []);
|
||||
|
||||
if (!user?.id) {
|
||||
return (
|
||||
<Button onClick={goToComments}>Login / Register to add comments</Button>
|
||||
);
|
||||
}
|
||||
|
||||
return <RenderComponents postId={postId} />;
|
||||
};
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
'use client';
|
||||
|
||||
import { Button } from '@gitroom/react/form/button';
|
||||
import copy from 'copy-to-clipboard';
|
||||
import { useCallback } from 'react';
|
||||
import { useToaster } from '@gitroom/react/toaster/toaster';
|
||||
|
||||
export const CopyClient = () => {
|
||||
const toast = useToaster();
|
||||
|
||||
const copyToClipboard = useCallback(() => {
|
||||
toast.show('Link copied to clipboard', 'success');
|
||||
copy(window.location.href.split?.('?')?.shift()!);
|
||||
}, []);
|
||||
|
||||
return <Button onClick={copyToClipboard}>Share with a client</Button>;
|
||||
};
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
'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';
|
||||
import { Toaster } from '@gitroom/react/toaster/toaster';
|
||||
|
||||
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}>
|
||||
<Toaster />
|
||||
{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/') || nextUrl.pathname.startsWith('/icons/')) {
|
||||
return NextResponse.next();
|
||||
}
|
||||
// If the URL is logout, delete the cookie and redirect to login
|
||||
|
|
|
|||
|
|
@ -1,168 +0,0 @@
|
|||
import { PrismaRepository } from '@gitroom/nestjs-libraries/database/prisma/prisma.service';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import dayjs from 'dayjs';
|
||||
import { groupBy } from 'lodash';
|
||||
|
||||
@Injectable()
|
||||
export class CommentsRepository {
|
||||
constructor(private _media: PrismaRepository<'comments'>) {}
|
||||
|
||||
addAComment(orgId: string, userId: string, comment: string, date: string) {
|
||||
return this._media.model.comments.create({
|
||||
data: {
|
||||
organizationId: orgId,
|
||||
userId: userId,
|
||||
content: comment,
|
||||
date: dayjs(date).toDate(),
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
addACommentToComment(
|
||||
orgId: string,
|
||||
userId: string,
|
||||
commentId: string,
|
||||
comment: string,
|
||||
date: string
|
||||
) {
|
||||
return this._media.model.comments.create({
|
||||
data: {
|
||||
organizationId: orgId,
|
||||
userId: userId,
|
||||
content: comment,
|
||||
date: dayjs(date).toDate(),
|
||||
parentCommentId: commentId,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
updateAComment(
|
||||
orgId: string,
|
||||
userId: string,
|
||||
commentId: string,
|
||||
comment: string
|
||||
) {
|
||||
return this._media.model.comments.update({
|
||||
where: {
|
||||
id: commentId,
|
||||
organizationId: orgId,
|
||||
userId: userId,
|
||||
},
|
||||
data: {
|
||||
content: comment,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
deleteAComment(orgId: string, userId: string, commentId: string) {
|
||||
return this._media.model.comments.update({
|
||||
where: {
|
||||
id: commentId,
|
||||
organizationId: orgId,
|
||||
userId: userId,
|
||||
},
|
||||
data: {
|
||||
deletedAt: new Date(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async loadAllCommentsAndSubCommentsForADate(orgId: string, date: string) {
|
||||
return this._media.model.comments.findMany({
|
||||
where: {
|
||||
organizationId: orgId,
|
||||
deletedAt: null,
|
||||
date: dayjs(date).toDate(),
|
||||
parentCommentId: null,
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: 'desc',
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
content: true,
|
||||
user: {
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
},
|
||||
},
|
||||
childrenComment: {
|
||||
where: {
|
||||
deletedAt: null,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
content: true,
|
||||
user: {
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async getAllCommentsByWeekYear(
|
||||
orgId: string,
|
||||
year: number,
|
||||
week: number,
|
||||
) {
|
||||
const dateYear = dayjs().year(year);
|
||||
const date = dateYear.isoWeek(week);
|
||||
const startDate = date.startOf('isoWeek').subtract(2, 'days').toDate();
|
||||
const endDate = date.endOf('isoWeek').add(2, 'days').toDate();
|
||||
|
||||
const load = await this._media.model.comments.findMany({
|
||||
where: {
|
||||
organizationId: orgId,
|
||||
deletedAt: null,
|
||||
parentCommentId: null,
|
||||
date: {
|
||||
gte: startDate,
|
||||
lte: endDate,
|
||||
},
|
||||
},
|
||||
select: {
|
||||
date: true,
|
||||
_count: {
|
||||
select: {
|
||||
childrenComment: {
|
||||
where: {
|
||||
deletedAt: null,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const group = groupBy(load, (item) =>
|
||||
dayjs(item.date).format('YYYY-MM-DD HH:MM')
|
||||
);
|
||||
|
||||
return Object.values(group).reduce((all, current) => {
|
||||
return [
|
||||
...all,
|
||||
{
|
||||
date: current[0].date,
|
||||
total:
|
||||
current.length +
|
||||
current.reduce(
|
||||
(all2, current2) => all2 + current2._count.childrenComment,
|
||||
0
|
||||
),
|
||||
},
|
||||
];
|
||||
}, [] as Array<{ date: Date; total: number }>);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
import { CommentsRepository } from '@gitroom/nestjs-libraries/database/prisma/comments/comments.repository';
|
||||
|
||||
@Injectable()
|
||||
export class CommentsService {
|
||||
constructor(private _commentsRepository: CommentsRepository) {}
|
||||
|
||||
addAComment(orgId: string, userId: string, comment: string, date: string) {
|
||||
return this._commentsRepository.addAComment(orgId, userId, comment, date);
|
||||
}
|
||||
|
||||
addACommentToComment(
|
||||
orgId: string,
|
||||
userId: string,
|
||||
commentId: string,
|
||||
comment: string,
|
||||
date: string
|
||||
) {
|
||||
return this._commentsRepository.addACommentToComment(orgId, userId, commentId, comment, date);
|
||||
}
|
||||
|
||||
updateAComment(
|
||||
orgId: string,
|
||||
userId: string,
|
||||
commentId: string,
|
||||
comment: string
|
||||
) {
|
||||
return this._commentsRepository.updateAComment(
|
||||
orgId,
|
||||
userId,
|
||||
commentId,
|
||||
comment
|
||||
);
|
||||
}
|
||||
|
||||
deleteAComment(orgId: string, userId: string, commentId: string) {
|
||||
return this._commentsRepository.deleteAComment(orgId, userId, commentId);
|
||||
}
|
||||
|
||||
loadAllCommentsAndSubCommentsForADate(orgId: string, date: string) {
|
||||
return this._commentsRepository.loadAllCommentsAndSubCommentsForADate(
|
||||
orgId,
|
||||
date
|
||||
);
|
||||
}
|
||||
|
||||
getAllCommentsByWeekYear(orgId: string, year: number, week: number) {
|
||||
return this._commentsRepository.getAllCommentsByWeekYear(orgId, year, week);
|
||||
}
|
||||
}
|
||||
|
|
@ -16,8 +16,6 @@ import { PostsRepository } from '@gitroom/nestjs-libraries/database/prisma/posts
|
|||
import { IntegrationManager } from '@gitroom/nestjs-libraries/integrations/integration.manager';
|
||||
import { MediaService } from '@gitroom/nestjs-libraries/database/prisma/media/media.service';
|
||||
import { MediaRepository } from '@gitroom/nestjs-libraries/database/prisma/media/media.repository';
|
||||
import { CommentsRepository } from '@gitroom/nestjs-libraries/database/prisma/comments/comments.repository';
|
||||
import { CommentsService } from '@gitroom/nestjs-libraries/database/prisma/comments/comments.service';
|
||||
import { NotificationsRepository } from '@gitroom/nestjs-libraries/database/prisma/notifications/notifications.repository';
|
||||
import { EmailService } from '@gitroom/nestjs-libraries/services/email.service';
|
||||
import { ItemUserRepository } from '@gitroom/nestjs-libraries/database/prisma/marketplace/item.user.repository';
|
||||
|
|
@ -56,13 +54,11 @@ import { TrackService } from '@gitroom/nestjs-libraries/track/track.service';
|
|||
MessagesRepository,
|
||||
MediaService,
|
||||
MediaRepository,
|
||||
CommentsRepository,
|
||||
ItemUserRepository,
|
||||
AgenciesService,
|
||||
AgenciesRepository,
|
||||
ItemUserService,
|
||||
MessagesService,
|
||||
CommentsService,
|
||||
IntegrationManager,
|
||||
ExtractContentService,
|
||||
OpenaiService,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ dayjs.extend(weekOfYear);
|
|||
export class PostsRepository {
|
||||
constructor(
|
||||
private _post: PrismaRepository<'post'>,
|
||||
private _popularPosts: PrismaRepository<'popularPosts'>
|
||||
private _popularPosts: PrismaRepository<'popularPosts'>,
|
||||
private _comments: PrismaRepository<'comments'>
|
||||
) {}
|
||||
|
||||
getOldPosts(orgId: string, date: string) {
|
||||
|
|
@ -471,4 +472,31 @@ export class PostsRepository {
|
|||
})
|
||||
);
|
||||
}
|
||||
|
||||
async getComments(postId: string) {
|
||||
return this._comments.model.comments.findMany({
|
||||
where: {
|
||||
postId,
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: 'asc',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
createComment(
|
||||
orgId: string,
|
||||
userId: string,
|
||||
postId: string,
|
||||
content: string
|
||||
) {
|
||||
return this._comments.model.comments.create({
|
||||
data: {
|
||||
organizationId: orgId,
|
||||
userId,
|
||||
postId,
|
||||
content,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,11 +52,15 @@ export class PostsService {
|
|||
isFirst
|
||||
);
|
||||
|
||||
if (!post) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
post!,
|
||||
...(post?.childrenPost?.length
|
||||
? await this.getPostsRecursively(
|
||||
post.childrenPost[0].id,
|
||||
post?.childrenPost?.[0]?.id,
|
||||
false,
|
||||
orgId,
|
||||
false
|
||||
|
|
@ -793,4 +797,12 @@ export class PostsService {
|
|||
|
||||
return date.clone().add(num, 'minutes').format('YYYY-MM-DDTHH:mm:00');
|
||||
}
|
||||
|
||||
getComments(postId: string) {
|
||||
return this._postRepository.getComments(postId);
|
||||
}
|
||||
|
||||
createComment(orgId: string, userId: string, postId: string, comment: string) {
|
||||
return this._postRepository.createComment(orgId, userId, postId, comment);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -301,20 +301,18 @@ model Comments {
|
|||
content String
|
||||
organizationId String
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
postId String
|
||||
post Post @relation(fields: [postId], references: [id])
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
date DateTime
|
||||
parentCommentId String?
|
||||
parentComment Comments? @relation("parentCommentId", fields: [parentCommentId], references: [id])
|
||||
childrenComment Comments[] @relation("parentCommentId")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
|
||||
@@index([createdAt])
|
||||
@@index([organizationId])
|
||||
@@index([date])
|
||||
@@index([userId])
|
||||
@@index([postId])
|
||||
@@index([deletedAt])
|
||||
}
|
||||
|
||||
|
|
@ -345,6 +343,7 @@ model Post {
|
|||
lastMessageId String?
|
||||
lastMessage Messages? @relation(fields: [lastMessageId], references: [id])
|
||||
payoutProblems PayoutProblems[]
|
||||
comments Comments[]
|
||||
error String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
|
|
|||
Loading…
Reference in New Issue