Skip to content

Commit df00777

Browse files
committed
feat: new provider - listmonk
1 parent ba6d035 commit df00777

File tree

18 files changed

+554
-11
lines changed

18 files changed

+554
-11
lines changed

.env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ GITHUB_CLIENT_ID=""
5050
GITHUB_CLIENT_SECRET=""
5151
BEEHIIVE_API_KEY=""
5252
BEEHIIVE_PUBLICATION_ID=""
53+
LISTMONK_DOMAIN=""
54+
LISTMONK_USER=""
55+
LISTMONK_API_KEY=""
56+
LISTMONK_LIST_ID=""
5357
THREADS_APP_ID=""
5458
THREADS_APP_SECRET=""
5559
FACEBOOK_APP_ID=""

apps/backend/src/services/auth/auth.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import { OrganizationService } from '@gitroom/nestjs-libraries/database/prisma/o
77
import { AuthService as AuthChecker } from '@gitroom/helpers/auth/auth.service';
88
import { ProvidersFactory } from '@gitroom/backend/services/auth/providers/providers.factory';
99
import dayjs from 'dayjs';
10-
import { NewsletterService } from '@gitroom/nestjs-libraries/services/newsletter.service';
1110
import { NotificationService } from '@gitroom/nestjs-libraries/database/prisma/notifications/notification.service';
1211
import { ForgotReturnPasswordDto } from '@gitroom/nestjs-libraries/dtos/auth/forgot-return.password.dto';
1312
import { EmailService } from '@gitroom/nestjs-libraries/services/email.service';
13+
import { NewsletterService } from '@gitroom/nestjs-libraries/newsletter/newsletter.service';
1414

1515
@Injectable()
1616
export class AuthService {
2.52 KB
Loading

apps/frontend/src/components/launches/add.provider.component.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ export const CustomVariables: FC<{
258258
});
259259
const submit = useCallback(
260260
async (data: FieldValues) => {
261+
modals.closeAll();
261262
gotoUrl(
262263
`/integrations/social/${identifier}?state=nostate&code=${Buffer.from(
263264
JSON.stringify(data)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
'use client';
2+
3+
import {
4+
PostComment,
5+
withProvider,
6+
} from '@gitroom/frontend/components/new-launch/providers/high.order.provider';
7+
import { ListmonkDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/listmonk.dto';
8+
import { Input } from '@gitroom/react/form/input';
9+
import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values';
10+
import { SelectList } from '@gitroom/frontend/components/new-launch/providers/listmonk/select.list';
11+
import { SelectTemplates } from '@gitroom/frontend/components/new-launch/providers/listmonk/select.templates';
12+
13+
const SettingsComponent = () => {
14+
const form = useSettings();
15+
16+
return (
17+
<>
18+
<Input label="Subject" {...form.register('subject')} />
19+
<Input label="Preview" {...form.register('preview')} />
20+
<SelectList {...form.register('list')} />
21+
<SelectTemplates {...form.register('templates')} />
22+
</>
23+
);
24+
};
25+
26+
export default withProvider({
27+
postComment: PostComment.POST,
28+
minimumCharacters: [],
29+
SettingsComponent: SettingsComponent,
30+
CustomPreviewComponent: undefined,
31+
dto: ListmonkDto,
32+
checkValidity: async (posts) => {
33+
if (
34+
posts.some(
35+
(p) => p.some((a) => a.path.indexOf('mp4') > -1) && p.length > 1
36+
)
37+
) {
38+
return 'You can only upload one video per post.';
39+
}
40+
41+
if (posts.some((p) => p.length > 4)) {
42+
return 'There can be maximum 4 pictures in a post.';
43+
}
44+
return true;
45+
},
46+
maximumCharacters: 300000,
47+
});
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
'use client';
2+
3+
import { FC, useEffect, useState } from 'react';
4+
import { Select } from '@gitroom/react/form/select';
5+
import { useT } from '@gitroom/react/translation/get.transation.service.client';
6+
import { useCustomProviderFunction } from '@gitroom/frontend/components/launches/helpers/use.custom.provider.function';
7+
import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values';
8+
export const SelectList: FC<{
9+
name: string;
10+
onChange: (event: {
11+
target: {
12+
value: string;
13+
name: string;
14+
};
15+
}) => void;
16+
}> = (props) => {
17+
const { onChange, name } = props;
18+
const t = useT();
19+
const customFunc = useCustomProviderFunction();
20+
const [orgs, setOrgs] = useState([]);
21+
const { getValues } = useSettings();
22+
const [currentMedia, setCurrentMedia] = useState<string | undefined>();
23+
const onChangeInner = (event: {
24+
target: {
25+
value: string;
26+
name: string;
27+
};
28+
}) => {
29+
setCurrentMedia(event.target.value);
30+
onChange(event);
31+
};
32+
useEffect(() => {
33+
customFunc.get('list').then((data) => setOrgs(data));
34+
const settings = getValues()[props.name];
35+
if (settings) {
36+
setCurrentMedia(settings);
37+
}
38+
}, []);
39+
if (!orgs.length) {
40+
return null;
41+
}
42+
return (
43+
<Select
44+
name={name}
45+
label="Select List"
46+
onChange={onChangeInner}
47+
value={currentMedia}
48+
>
49+
<option value="">{t('select_1', '--Select--')}</option>
50+
{orgs.map((org: any) => (
51+
<option key={org.id} value={org.id}>
52+
{org.name}
53+
</option>
54+
))}
55+
</Select>
56+
);
57+
};
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
'use client';
2+
3+
import { FC, useEffect, useState } from 'react';
4+
import { Select } from '@gitroom/react/form/select';
5+
import { useT } from '@gitroom/react/translation/get.transation.service.client';
6+
import { useCustomProviderFunction } from '@gitroom/frontend/components/launches/helpers/use.custom.provider.function';
7+
import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values';
8+
export const SelectTemplates: FC<{
9+
name: string;
10+
onChange: (event: {
11+
target: {
12+
value: string;
13+
name: string;
14+
};
15+
}) => void;
16+
}> = (props) => {
17+
const { onChange, name } = props;
18+
const t = useT();
19+
const customFunc = useCustomProviderFunction();
20+
const [orgs, setOrgs] = useState([]);
21+
const { getValues } = useSettings();
22+
const [currentMedia, setCurrentMedia] = useState<string | undefined>();
23+
const onChangeInner = (event: {
24+
target: {
25+
value: string;
26+
name: string;
27+
};
28+
}) => {
29+
setCurrentMedia(event.target.value);
30+
onChange(event);
31+
};
32+
useEffect(() => {
33+
customFunc.get('templates').then((data) => setOrgs(data));
34+
const settings = getValues()[props.name];
35+
if (settings) {
36+
setCurrentMedia(settings);
37+
}
38+
}, []);
39+
if (!orgs.length) {
40+
return null;
41+
}
42+
return (
43+
<Select
44+
name={name}
45+
label="Select Template"
46+
onChange={onChangeInner}
47+
value={currentMedia}
48+
>
49+
<option value="">{t('select_1', '--Select--')}</option>
50+
{orgs.map((org: any) => (
51+
<option key={org.id} value={org.id}>
52+
{org.name}
53+
</option>
54+
))}
55+
</Select>
56+
);
57+
};

apps/frontend/src/components/new-launch/providers/show.all.providers.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { Button } from '@gitroom/react/form/button';
3131
import { useT } from '@gitroom/react/translation/get.transation.service.client';
3232
import { PostComment } from '@gitroom/frontend/components/new-launch/providers/high.order.provider';
3333
import WordpressProvider from '@gitroom/frontend/components/new-launch/providers/wordpress/wordpress.provider';
34+
import ListmonkProvider from '@gitroom/frontend/components/new-launch/providers/listmonk/listmonk.provider';
3435

3536
export const Providers = [
3637
{
@@ -133,6 +134,10 @@ export const Providers = [
133134
identifier: 'wordpress',
134135
component: WordpressProvider,
135136
},
137+
{
138+
identifier: 'listmonk',
139+
component: ListmonkProvider,
140+
},
136141
];
137142
export const ShowAllProviders = forwardRef((props, ref) => {
138143
const { date, current, global, selectedIntegrations, allIntegrations } =

libraries/nestjs-libraries/src/dtos/posts/providers-settings/all.providers.settings.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { MediumSettingsDto } from '@gitroom/nestjs-libraries/dtos/posts/provider
1414
import { DevToSettingsDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/dev.to.settings.dto';
1515
import { HashnodeSettingsDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/hashnode.settings.dto';
1616
import { WordpressDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/wordpress.dto';
17+
import { ListmonkDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/listmonk.dto';
1718

1819
export type ProviderExtension<T extends string, M> = { __type: T } & M;
1920
export type AllProvidersSettings =
@@ -34,6 +35,7 @@ export type AllProvidersSettings =
3435
| ProviderExtension<'devto', DevToSettingsDto>
3536
| ProviderExtension<'hashnode', HashnodeSettingsDto>
3637
| ProviderExtension<'wordpress', WordpressDto>
38+
| ProviderExtension<'listmonk', ListmonkDto>
3739
| ProviderExtension<'facebook', None>
3840
| ProviderExtension<'threads', None>
3941
| ProviderExtension<'mastodon', None>
@@ -64,6 +66,7 @@ export const allProviders = (setEmpty?: any) => {
6466
{ value: DevToSettingsDto, name: 'devto' },
6567
{ value: WordpressDto, name: 'wordpress' },
6668
{ value: HashnodeSettingsDto, name: 'hashnode' },
69+
{ value: ListmonkDto, name: 'listmonk' },
6770
{ value: setEmpty, name: 'facebook' },
6871
{ value: setEmpty, name: 'threads' },
6972
{ value: setEmpty, name: 'mastodon' },
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { IsOptional, IsString, MinLength } from 'class-validator';
2+
3+
export class ListmonkDto {
4+
@IsString()
5+
@MinLength(1)
6+
subject: string;
7+
8+
@IsString()
9+
preview: string;
10+
11+
@IsString()
12+
list: string;
13+
14+
@IsString()
15+
@IsOptional()
16+
template: string;
17+
}

0 commit comments

Comments
 (0)