feat: update payment method, fix dev
This commit is contained in:
parent
ea2e32fa96
commit
d53bd606aa
|
|
@ -33,7 +33,7 @@ export class BillingController {
|
|||
return this._stripeService.subscribe(org.id, body);
|
||||
}
|
||||
|
||||
@Post('/modify')
|
||||
@Get('/portal')
|
||||
async modifyPayment(@GetOrgFromRequest() org: Organization) {
|
||||
const customer = await this._stripeService.getCustomerByOrganizationId(
|
||||
org.id
|
||||
|
|
|
|||
|
|
@ -132,6 +132,7 @@ export class IntegrationsController {
|
|||
throw new Error('Invalid api key');
|
||||
}
|
||||
|
||||
console.log('asd');
|
||||
return this._integrationService.createOrUpdateIntegration(
|
||||
org.id,
|
||||
name,
|
||||
|
|
|
|||
|
|
@ -278,3 +278,6 @@ html {
|
|||
font-size: 20px !important;
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
.auto-width {
|
||||
width: auto !important;
|
||||
}
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
import { FC } from 'react';
|
||||
import { StarsAndForksInterface } from '@gitroom/frontend/components/analytics/stars.and.forks.interface';
|
||||
import { Chart } from '@gitroom/frontend/components/analytics/chart';
|
||||
import Image from 'next/image';
|
||||
import { UtcToLocalDateRender } from '../../../../../libraries/react-shared-libraries/src/helpers/utc.date.render';
|
||||
import { UtcToLocalDateRender } from '@gitroom/react/helpers/utc.date.render';
|
||||
import clsx from 'clsx';
|
||||
|
||||
export const StarsAndForks: FC<StarsAndForksInterface> = (props) => {
|
||||
|
|
@ -11,47 +10,91 @@ export const StarsAndForks: FC<StarsAndForksInterface> = (props) => {
|
|||
<>
|
||||
{list.map((item) => (
|
||||
<div className="flex gap-[24px] h-[272px]" key={item.login}>
|
||||
{[1, 2].map((p) => (
|
||||
<div
|
||||
key={p}
|
||||
className="flex-1 bg-secondary py-[10px] px-[16px] flex flex-col"
|
||||
>
|
||||
<div className="flex items-center gap-[14px]">
|
||||
<div>
|
||||
<Image
|
||||
src="/icons/star-circle.svg"
|
||||
alt="Stars"
|
||||
width={40}
|
||||
height={40}
|
||||
<div className="flex-1 bg-secondary py-[10px] px-[16px] flex flex-col">
|
||||
<div className="flex items-center gap-[14px]">
|
||||
<div className="bg-[#28344F] p-[8px]">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M18.7011 5.47658C18.639 5.28266 18.5206 5.11156 18.3611 4.98499C18.2015 4.85842 18.008 4.78208 17.805 4.76564L14.8972 4.51955L13.7628 1.87502C13.6828 1.68962 13.5502 1.53172 13.3815 1.42078C13.2127 1.30985 13.0152 1.25073 12.8132 1.25073C12.6113 1.25073 12.4138 1.30985 12.245 1.42078C12.0763 1.53172 11.9437 1.68962 11.8636 1.87502L10.7293 4.52033L7.82066 4.76564C7.61869 4.78187 7.42605 4.85754 7.26704 4.98311C7.10803 5.10869 6.98977 5.27854 6.92718 5.47125C6.86459 5.66396 6.86047 5.87088 6.91534 6.06593C6.97021 6.26097 7.08162 6.4354 7.2355 6.56721L9.4355 8.44221L8.77691 11.2336C8.73061 11.4293 8.74296 11.6342 8.81243 11.8229C8.8819 12.0116 9.00541 12.1756 9.16753 12.2945C9.33158 12.415 9.52749 12.4845 9.73078 12.4942C9.93406 12.5039 10.1357 12.4535 10.3105 12.3492L12.8105 10.8649L15.3105 12.3492C15.4853 12.4535 15.6869 12.5039 15.8902 12.4942C16.0935 12.4845 16.2894 12.415 16.4535 12.2945C16.6157 12.1757 16.7392 12.0117 16.8087 11.823C16.8782 11.6343 16.8905 11.4293 16.8441 11.2336L16.1855 8.44221L18.3847 6.56721C18.5395 6.43716 18.6522 6.26409 18.7085 6.06994C18.7649 5.87578 18.7623 5.66927 18.7011 5.47658ZM15.2746 7.58596C15.1306 7.70792 15.0233 7.86741 14.9645 8.04671C14.9058 8.226 14.8979 8.41807 14.9418 8.60158L15.5128 11.0235L13.3425 9.73361C13.1824 9.63811 12.9993 9.5877 12.8128 9.5877C12.6264 9.5877 12.4433 9.63811 12.2832 9.73361L10.1128 11.0156L10.6839 8.59377C10.7284 8.41035 10.7209 8.21816 10.6623 8.03876C10.6036 7.85937 10.4962 7.69986 10.3519 7.57814L8.4566 5.96721L10.9636 5.75471C11.1497 5.73909 11.328 5.6731 11.4794 5.56382C11.6308 5.45453 11.7496 5.30608 11.823 5.13439L12.8128 2.83127L13.8003 5.13439C13.8739 5.30598 13.9927 5.45434 14.1441 5.56361C14.2955 5.67287 14.4737 5.73893 14.6597 5.75471L17.1668 5.96721L15.2746 7.58596ZM6.69254 9.81721L2.31754 14.1922C2.20026 14.3095 2.0412 14.3754 1.87535 14.3754C1.7095 14.3754 1.55044 14.3095 1.43316 14.1922C1.31588 14.0749 1.25 13.9159 1.25 13.75C1.25 13.5842 1.31588 13.4251 1.43316 13.3078L5.80816 8.93283C5.92544 8.81556 6.0845 8.74967 6.25035 8.74967C6.4162 8.74967 6.57526 8.81556 6.69254 8.93283C6.80981 9.05011 6.87569 9.20917 6.8757 9.37502C6.8757 9.54087 6.80981 9.69993 6.69254 9.81721ZM7.94254 14.1922L3.56753 18.5672C3.50947 18.6253 3.44053 18.6713 3.36466 18.7028C3.28879 18.7342 3.20747 18.7504 3.12535 18.7504C3.04323 18.7504 2.96191 18.7342 2.88604 18.7028C2.81017 18.6713 2.74123 18.6253 2.68316 18.5672C2.62509 18.5091 2.57903 18.4402 2.5476 18.3643C2.51618 18.2885 2.5 18.2071 2.5 18.125C2.5 18.0429 2.51618 17.9616 2.5476 17.8857C2.57903 17.8098 2.62509 17.7409 2.68316 17.6828L7.05816 13.3078C7.17544 13.1906 7.3345 13.1247 7.50035 13.1247C7.6662 13.1247 7.82526 13.1906 7.94254 13.3078C8.05981 13.4251 8.12569 13.5842 8.1257 13.75C8.1257 13.9159 8.05981 14.0749 7.94254 14.1922ZM13.5675 13.3078C13.6256 13.3659 13.6717 13.4348 13.7032 13.5107C13.7347 13.5866 13.7508 13.6679 13.7508 13.75C13.7508 13.8322 13.7347 13.9135 13.7032 13.9894C13.6717 14.0652 13.6256 14.1342 13.5675 14.1922L9.19254 18.5672C9.13447 18.6253 9.06553 18.6713 8.98966 18.7028C8.91379 18.7342 8.83247 18.7504 8.75035 18.7504C8.66823 18.7504 8.58691 18.7342 8.51104 18.7028C8.43517 18.6713 8.36623 18.6253 8.30816 18.5672C8.25009 18.5091 8.20403 18.4402 8.1726 18.3643C8.14117 18.2885 8.125 18.2071 8.125 18.125C8.125 18.0429 8.14117 17.9616 8.1726 17.8857C8.20403 17.8098 8.25009 17.7409 8.30816 17.6828L12.6832 13.3078C12.7412 13.2497 12.8101 13.2036 12.886 13.1722C12.9619 13.1407 13.0432 13.1245 13.1253 13.1245C13.2075 13.1245 13.2888 13.1407 13.3647 13.1722C13.4406 13.2036 13.5095 13.2497 13.5675 13.3078Z"
|
||||
fill="white"
|
||||
/>
|
||||
</div>
|
||||
<div className="text-[20px]">
|
||||
{item.login
|
||||
.split('/')[1]
|
||||
.split('')
|
||||
.map((char, index) =>
|
||||
index === 0 ? char.toUpperCase() : char
|
||||
)
|
||||
.join('')}{' '}
|
||||
{p === 1 ? 'Stars' : 'Forks'}
|
||||
</div>
|
||||
</svg>
|
||||
</div>
|
||||
<div className="flex-1 relative">
|
||||
<div className="absolute w-full h-full left-0 top-0">
|
||||
{item.stars.length ? (
|
||||
<Chart list={item.stars} />
|
||||
) : (
|
||||
<div className="w-full h-full flex items-center justify-center text-3xl">
|
||||
Processing stars...
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-[50px] leading-[60px]">
|
||||
{item?.stars[item.stars.length - 1]?.totalStars}
|
||||
<div className="text-[20px]">
|
||||
{item.login
|
||||
.split('/')[1]
|
||||
.split('')
|
||||
.map((char, index) =>
|
||||
index === 0 ? char.toUpperCase() : char
|
||||
)
|
||||
.join('')}{' '}
|
||||
Stars
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
<div className="flex-1 relative">
|
||||
<div className="absolute w-full h-full left-0 top-0">
|
||||
{item.stars.length ? (
|
||||
<Chart list={item.stars} />
|
||||
) : (
|
||||
<div className="w-full h-full flex items-center justify-center text-3xl">
|
||||
Processing stars...
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-[50px] leading-[60px]">
|
||||
{item?.stars[item.stars.length - 1]?.totalStars}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 bg-secondary py-[10px] px-[16px] flex flex-col">
|
||||
<div className="flex items-center gap-[14px]">
|
||||
<div className="bg-[#28344F] p-[8px]">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M16.7863 14.0719C16.7441 14.1425 16.6883 14.204 16.6222 14.253C16.5561 14.302 16.481 14.3375 16.4011 14.3574C16.3213 14.3773 16.2383 14.3812 16.1569 14.3689C16.0755 14.3567 15.9974 14.3285 15.927 14.2859L10.6254 11.1039V16.875C10.6254 17.0408 10.5596 17.1997 10.4423 17.3169C10.3251 17.4342 10.1662 17.5 10.0004 17.5C9.83464 17.5 9.67567 17.4342 9.55846 17.3169C9.44125 17.1997 9.3754 17.0408 9.3754 16.875V11.1039L4.07228 14.2859C4.00187 14.3292 3.92358 14.3581 3.84195 14.3709C3.76031 14.3837 3.67695 14.3801 3.59668 14.3605C3.51641 14.3409 3.44083 14.3055 3.37431 14.2565C3.30779 14.2075 3.25166 14.1458 3.20915 14.0749C3.16664 14.004 3.13861 13.9255 3.12667 13.8437C3.11474 13.7619 3.11913 13.6786 3.13961 13.5985C3.16008 13.5185 3.19623 13.4433 3.24595 13.3773C3.29568 13.3113 3.358 13.2558 3.42931 13.2141L8.78556 10L3.42931 6.78594C3.358 6.74418 3.29568 6.6887 3.24595 6.62271C3.19623 6.55671 3.16008 6.48151 3.13961 6.40145C3.11913 6.3214 3.11474 6.23808 3.12667 6.15631C3.13861 6.07454 3.16664 5.99595 3.20915 5.92509C3.25166 5.85423 3.30779 5.7925 3.37431 5.74348C3.44083 5.69445 3.51641 5.6591 3.59668 5.63948C3.67695 5.61985 3.76031 5.61634 3.84195 5.62914C3.92358 5.64194 4.00187 5.67081 4.07228 5.71406L9.3754 8.89609V3.125C9.3754 2.95924 9.44125 2.80027 9.55846 2.68306C9.67567 2.56585 9.83464 2.5 10.0004 2.5C10.1662 2.5 10.3251 2.56585 10.4423 2.68306C10.5596 2.80027 10.6254 2.95924 10.6254 3.125V8.89609L15.9285 5.71406C15.9989 5.67081 16.0772 5.64194 16.1589 5.62914C16.2405 5.61634 16.3239 5.61985 16.4041 5.63948C16.4844 5.6591 16.56 5.69445 16.6265 5.74348C16.693 5.7925 16.7491 5.85423 16.7917 5.92509C16.8342 5.99595 16.8622 6.07454 16.8741 6.15631C16.8861 6.23808 16.8817 6.3214 16.8612 6.40145C16.8407 6.48151 16.8046 6.55671 16.7549 6.62271C16.7051 6.6887 16.6428 6.74418 16.5715 6.78594L11.2152 10L16.5715 13.2141C16.642 13.2563 16.7034 13.3119 16.7524 13.3779C16.8013 13.4438 16.8367 13.5188 16.8567 13.5984C16.8767 13.6781 16.8807 13.7609 16.8686 13.8422C16.8566 13.9234 16.8286 14.0015 16.7863 14.0719Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div className="text-[20px]">
|
||||
{item.login
|
||||
.split('/')[1]
|
||||
.split('')
|
||||
.map((char, index) =>
|
||||
index === 0 ? char.toUpperCase() : char
|
||||
)
|
||||
.join('')}{' '}
|
||||
Forks
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 relative">
|
||||
<div className="absolute w-full h-full left-0 top-0">
|
||||
{item.stars.length ? (
|
||||
<Chart list={item.stars} />
|
||||
) : (
|
||||
<div className="w-full h-full flex items-center justify-center text-3xl">
|
||||
Processing stars...
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-[50px] leading-[60px]">
|
||||
{item?.stars[item.stars.length - 1]?.totalStars}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
<div className="flex gap-[24px]">
|
||||
|
|
@ -61,13 +104,34 @@ export const StarsAndForks: FC<StarsAndForksInterface> = (props) => {
|
|||
className="flex-1 bg-secondary py-[24px] px-[16px] gap-[16px] flex flex-col"
|
||||
>
|
||||
<div className="flex items-center gap-[14px]">
|
||||
<div>
|
||||
<Image
|
||||
src="/icons/trending.svg"
|
||||
width={36}
|
||||
height={36}
|
||||
alt="Trending"
|
||||
/>
|
||||
<div className="p-[8px] bg-[#28344F]">
|
||||
{p === 0 ? (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M18.125 16.25C18.125 16.4158 18.0592 16.5747 17.9419 16.6919C17.8247 16.8092 17.6658 16.875 17.5 16.875H2.5C2.33424 16.875 2.17527 16.8092 2.05806 16.6919C1.94085 16.5747 1.875 16.4158 1.875 16.25V3.75C1.875 3.58424 1.94085 3.42527 2.05806 3.30806C2.17527 3.19085 2.33424 3.125 2.5 3.125C2.66576 3.125 2.82473 3.19085 2.94194 3.30806C3.05915 3.42527 3.125 3.58424 3.125 3.75V12.2414L7.05781 8.30781C7.11586 8.2497 7.18479 8.2036 7.26066 8.17215C7.33654 8.1407 7.41787 8.12451 7.5 8.12451C7.58213 8.12451 7.66346 8.1407 7.73934 8.17215C7.81521 8.2036 7.88414 8.2497 7.94219 8.30781L10 10.3664L14.1164 6.25H12.5C12.3342 6.25 12.1753 6.18415 12.0581 6.06694C11.9408 5.94973 11.875 5.79076 11.875 5.625C11.875 5.45924 11.9408 5.30027 12.0581 5.18306C12.1753 5.06585 12.3342 5 12.5 5H15.625C15.7908 5 15.9497 5.06585 16.0669 5.18306C16.1842 5.30027 16.25 5.45924 16.25 5.625V8.75C16.25 8.91576 16.1842 9.07473 16.0669 9.19194C15.9497 9.30915 15.7908 9.375 15.625 9.375C15.4592 9.375 15.3003 9.30915 15.1831 9.19194C15.0658 9.07473 15 8.91576 15 8.75V7.13359L10.4422 11.6922C10.3841 11.7503 10.3152 11.7964 10.2393 11.8279C10.1635 11.8593 10.0821 11.8755 10 11.8755C9.91787 11.8755 9.83654 11.8593 9.76066 11.8279C9.68479 11.7964 9.61586 11.7503 9.55781 11.6922L7.5 9.63359L3.125 14.0086V15.625H17.5C17.6658 15.625 17.8247 15.6908 17.9419 15.8081C18.0592 15.9253 18.125 16.0842 18.125 16.25Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
) : (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M18.7503 4.375V9.375C18.7503 9.54076 18.6845 9.69973 18.5673 9.81694C18.4501 9.93415 18.2911 10 18.1253 10C17.9596 10 17.8006 9.93415 17.6834 9.81694C17.5662 9.69973 17.5003 9.54076 17.5003 9.375V5.88359L11.0675 12.3172C11.0095 12.3753 10.9406 12.4214 10.8647 12.4529C10.7888 12.4843 10.7075 12.5005 10.6253 12.5005C10.5432 12.5005 10.4619 12.4843 10.386 12.4529C10.3101 12.4214 10.2412 12.3753 10.1832 12.3172L7.50035 9.63359L2.31753 14.8172C2.20026 14.9345 2.0412 15.0003 1.87535 15.0003C1.7095 15.0003 1.55044 14.9345 1.43316 14.8172C1.31588 14.6999 1.25 14.5409 1.25 14.375C1.25 14.2091 1.31588 14.0501 1.43316 13.9328L7.05816 8.30781C7.1162 8.2497 7.18514 8.2036 7.26101 8.17215C7.33688 8.1407 7.41821 8.12451 7.50035 8.12451C7.58248 8.12451 7.66381 8.1407 7.73968 8.17215C7.81556 8.2036 7.88449 8.2497 7.94253 8.30781L10.6253 10.9914L16.6168 5H13.1253C12.9596 5 12.8006 4.93415 12.6834 4.81694C12.5662 4.69973 12.5003 4.54076 12.5003 4.375C12.5003 4.20924 12.5662 4.05027 12.6834 3.93306C12.8006 3.81585 12.9596 3.75 13.1253 3.75H18.1253C18.2911 3.75 18.4501 3.81585 18.5673 3.93306C18.6845 4.05027 18.7503 4.20924 18.7503 4.375Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-[20px]">
|
||||
{p === 0
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
'use client';
|
||||
|
||||
import {useCallback, useEffect, useState} from 'react';
|
||||
import { NoBillingComponent } from '@gitroom/frontend/components/billing/no.billing.component';
|
||||
import { useCallback } from 'react';
|
||||
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';
|
||||
|
||||
export const BillingComponent = () => {
|
||||
const fetch = useFetch();
|
||||
|
|
@ -26,5 +26,7 @@ export const BillingComponent = () => {
|
|||
return <LoadingComponent />;
|
||||
}
|
||||
|
||||
return <NoBillingComponent tiers={tiers} sub={subscription?.subscription} />;
|
||||
return (
|
||||
<MainBillingComponent tiers={tiers} sub={subscription?.subscription} />
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ export const Features: FC<{
|
|||
);
|
||||
};
|
||||
|
||||
export const NoBillingComponent: FC<{
|
||||
export const MainBillingComponent: FC<{
|
||||
tiers: Tiers;
|
||||
sub?: Subscription;
|
||||
}> = (props) => {
|
||||
|
|
@ -191,6 +191,11 @@ export const NoBillingComponent: FC<{
|
|||
setSubscription(sub);
|
||||
}, [sub]);
|
||||
|
||||
const updatePayment = useCallback(async () => {
|
||||
const { portal } = await (await fetch('/billing/portal')).json();
|
||||
window.location.href = portal;
|
||||
}, []);
|
||||
|
||||
const currentPackage = useMemo(() => {
|
||||
if (!subscription) {
|
||||
return 'FREE';
|
||||
|
|
@ -226,9 +231,7 @@ export const NoBillingComponent: FC<{
|
|||
const beforeTotalChannels = pricing[billing].channel || initialChannels;
|
||||
|
||||
if (totalChannels < beforeTotalChannels) {
|
||||
messages.push(
|
||||
`Some of the channels will be disabled`
|
||||
);
|
||||
messages.push(`Some of the channels will be disabled`);
|
||||
}
|
||||
|
||||
if (
|
||||
|
|
@ -244,7 +247,9 @@ export const NoBillingComponent: FC<{
|
|||
if (
|
||||
subscription?.cancelAt ||
|
||||
(await deleteDialog(
|
||||
`Are you sure you want to cancel your subscription? ${messages.join(', ')}`,
|
||||
`Are you sure you want to cancel your subscription? ${messages.join(
|
||||
', '
|
||||
)}`,
|
||||
'Yes, cancel',
|
||||
'Cancel Subscription'
|
||||
))
|
||||
|
|
@ -266,8 +271,11 @@ export const NoBillingComponent: FC<{
|
|||
return;
|
||||
}
|
||||
|
||||
if (messages.length && !await deleteDialog(messages.join(', '), 'Yes, continue')) {
|
||||
return ;
|
||||
if (
|
||||
messages.length &&
|
||||
!(await deleteDialog(messages.join(', '), 'Yes, continue'))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
|
|
@ -419,6 +427,11 @@ export const NoBillingComponent: FC<{
|
|||
</div>
|
||||
))}
|
||||
</div>
|
||||
{!!subscription?.id && (
|
||||
<div className="flex justify-center mt-[20px]">
|
||||
<Button onClick={updatePayment}>Update Payment Method</Button>
|
||||
</div>
|
||||
)}
|
||||
<FAQComponent />
|
||||
</div>
|
||||
);
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
'use client';
|
||||
|
||||
import { useModals } from '@mantine/modals';
|
||||
import { FC, useCallback } from 'react';
|
||||
import React, { FC, useCallback } from 'react';
|
||||
import { useFetch } from '@gitroom/helpers/utils/custom.fetch';
|
||||
import { Input } from '@gitroom/react/form/input';
|
||||
import { FieldValues, FormProvider, useForm } from 'react-hook-form';
|
||||
|
|
@ -9,34 +9,43 @@ import { Button } from '@gitroom/react/form/button';
|
|||
import { classValidatorResolver } from '@hookform/resolvers/class-validator';
|
||||
import { ApiKeyDto } from '@gitroom/nestjs-libraries/dtos/integrations/api.key.dto';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { TopTitle } from '@gitroom/frontend/components/launches/helpers/top.title.component';
|
||||
|
||||
const resolver = classValidatorResolver(ApiKeyDto);
|
||||
|
||||
export const useAddProvider = () => {
|
||||
export const useAddProvider = (update?: () => void) => {
|
||||
const modal = useModals();
|
||||
const fetch = useFetch();
|
||||
return useCallback(async () => {
|
||||
const data = await (await fetch('/integrations')).json();
|
||||
modal.openModal({
|
||||
title: 'Add Channel',
|
||||
children: <AddProviderComponent {...data} />,
|
||||
title: '',
|
||||
withCloseButton: false,
|
||||
classNames: {
|
||||
modal: 'bg-transparent text-white',
|
||||
},
|
||||
children: <AddProviderComponent update={update} {...data} />,
|
||||
size: 'auto',
|
||||
});
|
||||
}, []);
|
||||
};
|
||||
|
||||
export const AddProviderButton = () => {
|
||||
const add = useAddProvider();
|
||||
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}
|
||||
>
|
||||
<button className="text-white p-[8px] rounded-md bg-forth" onClick={add}>
|
||||
Add Channel
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export const ApiModal: FC<{ identifier: string; name: string }> = (props) => {
|
||||
export const ApiModal: FC<{
|
||||
identifier: string;
|
||||
name: string;
|
||||
update?: () => void;
|
||||
}> = (props) => {
|
||||
const { update, name } = props;
|
||||
const fetch = useFetch();
|
||||
const router = useRouter();
|
||||
const modal = useModals();
|
||||
|
|
@ -45,6 +54,10 @@ export const ApiModal: FC<{ identifier: string; name: string }> = (props) => {
|
|||
resolver,
|
||||
});
|
||||
|
||||
const close = useCallback(() => {
|
||||
modal.closeAll();
|
||||
}, []);
|
||||
|
||||
const submit = useCallback(async (data: FieldValues) => {
|
||||
const add = await fetch(
|
||||
`/integrations/article/${props.identifier}/connect`,
|
||||
|
|
@ -57,6 +70,7 @@ export const ApiModal: FC<{ identifier: string; name: string }> = (props) => {
|
|||
if (add.ok) {
|
||||
modal.closeAll();
|
||||
router.refresh();
|
||||
if (update) update();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -66,25 +80,51 @@ export const ApiModal: FC<{ identifier: string; name: string }> = (props) => {
|
|||
}, []);
|
||||
|
||||
return (
|
||||
<FormProvider {...methods}>
|
||||
<form
|
||||
className="gap-[8px] flex flex-col"
|
||||
onSubmit={methods.handleSubmit(submit)}
|
||||
<div className="rounded-[4px] border border-[#172034] bg-[#0B101B] px-[16px] pb-[16px] relative">
|
||||
<TopTitle title={`Add API key for ${name}`} />
|
||||
<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"
|
||||
>
|
||||
<div>
|
||||
<Input label="API Key" name="api" />
|
||||
</div>
|
||||
<div>
|
||||
<Button type="submit">Add platform</Button>
|
||||
</div>
|
||||
</form>
|
||||
</FormProvider>
|
||||
<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>
|
||||
<FormProvider {...methods}>
|
||||
<form
|
||||
className="gap-[8px] flex flex-col"
|
||||
onSubmit={methods.handleSubmit(submit)}
|
||||
>
|
||||
<div className="pt-[10px]">
|
||||
<Input label="API Key" name="api" />
|
||||
</div>
|
||||
<div>
|
||||
<Button type="submit">Add platform</Button>
|
||||
</div>
|
||||
</form>
|
||||
</FormProvider>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export const AddProviderComponent: FC<{
|
||||
social: Array<{ identifier: string; name: string }>;
|
||||
article: Array<{ identifier: string; name: string }>;
|
||||
update?: () => void;
|
||||
}> = (props) => {
|
||||
const { update } = props;
|
||||
|
||||
const fetch = useFetch();
|
||||
const modal = useModals();
|
||||
const { social, article } = props;
|
||||
|
|
@ -98,41 +138,84 @@ export const AddProviderComponent: FC<{
|
|||
[]
|
||||
);
|
||||
|
||||
const close = useCallback(() => {
|
||||
modal.closeAll();
|
||||
}, []);
|
||||
|
||||
const showApiButton = useCallback(
|
||||
(identifier: string, name: string) => async () => {
|
||||
modal.openModal({
|
||||
title: `Add ${name}`,
|
||||
children: <ApiModal name={name} identifier={identifier} />,
|
||||
title: '',
|
||||
withCloseButton: false,
|
||||
classNames: {
|
||||
modal: 'bg-transparent text-white',
|
||||
},
|
||||
children: (
|
||||
<ApiModal update={update} name={name} identifier={identifier} />
|
||||
),
|
||||
});
|
||||
},
|
||||
[]
|
||||
);
|
||||
return (
|
||||
<div className="w-full flex flex-col gap-[20px]">
|
||||
<div className="w-full flex flex-col gap-[20px] rounded-[4px] border border-[#172034] bg-[#0B101B] px-[16px] pb-[16px] relative">
|
||||
<div className="flex flex-col">
|
||||
<h2>Social</h2>
|
||||
<TopTitle title="Add Channel" />
|
||||
<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>
|
||||
<h2 className="pt-[16px] pb-[10px]">Social</h2>
|
||||
<div className="flex flex-wrap gap-[10px]">
|
||||
{social.map((item) => (
|
||||
<div
|
||||
key={item.identifier}
|
||||
onClick={getSocialLink(item.identifier)}
|
||||
className="w-[100px] h-[100px] bg-forth text-white justify-center items-center flex"
|
||||
className="w-[120px] h-[100px] bg-input text-white justify-center items-center flex flex-col gap-[10px] cursor-pointer"
|
||||
>
|
||||
{item.name}
|
||||
<div>
|
||||
<img
|
||||
className="w-[32px] h-[32px] rounded-full"
|
||||
src={`/icons/platforms/${item.identifier}.png`}
|
||||
/>
|
||||
</div>
|
||||
<div>{item.name}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<h2>Articles</h2>
|
||||
<h2 className="pb-[10px]">Articles</h2>
|
||||
<div className="flex flex-wrap gap-[10px]">
|
||||
{article.map((item) => (
|
||||
<div
|
||||
key={item.identifier}
|
||||
onClick={showApiButton(item.identifier, item.name)}
|
||||
className="w-[100px] h-[100px] bg-forth text-white justify-center items-center flex"
|
||||
className="w-[120px] h-[100px] bg-input text-white justify-center items-center flex flex-col gap-[10px] cursor-pointer"
|
||||
>
|
||||
{item.name}
|
||||
<div>
|
||||
<img
|
||||
className="w-[32px] h-[32px] rounded-full"
|
||||
src={`/icons/platforms/${item.identifier}.png`}
|
||||
/>
|
||||
</div>
|
||||
<div>{item.name}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ const CalendarColumnRender: FC<{ day: number; hour: string }> = (props) => {
|
|||
closeOnEscape: false,
|
||||
withCloseButton: false,
|
||||
classNames: {
|
||||
modal: 'bg-transparent text-white',
|
||||
modal: 'bg-transparent text-white !w-[auto]',
|
||||
},
|
||||
children: (
|
||||
<ExistingDataContextProvider value={data}>
|
||||
|
|
@ -277,7 +277,7 @@ const CalendarColumnRender: FC<{ day: number; hour: string }> = (props) => {
|
|||
/>
|
||||
</ExistingDataContextProvider>
|
||||
),
|
||||
size: '80%',
|
||||
size: 'dynamic',
|
||||
title: ``,
|
||||
});
|
||||
},
|
||||
|
|
@ -293,7 +293,7 @@ const CalendarColumnRender: FC<{ day: number; hour: string }> = (props) => {
|
|||
modal: 'bg-transparent text-white',
|
||||
},
|
||||
children: <AddEditModal integrations={integrations} date={getDate} />,
|
||||
size: '80%',
|
||||
size: '80%'
|
||||
// title: `Adding posts for ${getDate.format('DD/MM/YYYY HH:mm')}`,
|
||||
});
|
||||
}, []);
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ export const LaunchesComponent = () => {
|
|||
</div>
|
||||
))}
|
||||
</div>
|
||||
<AddProviderButton />
|
||||
<AddProviderButton update={() => update(true)} />
|
||||
</div>
|
||||
<div className="flex-1 flex flex-col gap-[14px]">
|
||||
<Filters />
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ export class IntegrationRepository {
|
|||
: {}),
|
||||
internalId,
|
||||
organizationId: org,
|
||||
deletedAt: null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,6 +191,12 @@ export class StripeService {
|
|||
return stripe.billingPortal.sessions.create({
|
||||
customer,
|
||||
flow_data: {
|
||||
after_completion: {
|
||||
type: 'redirect',
|
||||
redirect: {
|
||||
return_url: process.env['FRONTEND_URL'] + '/billing',
|
||||
},
|
||||
},
|
||||
type: 'payment_method_update',
|
||||
},
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue