Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added apps/frontend/public/icons/platforms/ghost.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
'use client';

import { FC } from 'react';
import {
PostComment,
withProvider,
} from '@gitroom/frontend/components/new-launch/providers/high.order.provider';
import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values';
import { Input } from '@gitroom/react/form/input';
import { Select } from '@gitroom/react/form/select';
import { MediaComponent } from '@gitroom/frontend/components/media/media.component';
import { GhostTags } from '@gitroom/frontend/components/new-launch/providers/ghost/ghost.tags';
import { GhostDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/ghost.dto';

const GhostSettings: FC = () => {
const form = useSettings();
return (
<>
<Input label="Title" {...form.register('title')} />
<Input
label="Slug (optional)"
{...form.register('slug')}
/>
<Select label="Status" name="status" defaultValue="published">
<option value="published">Published</option>
<option value="draft">Draft</option>
</Select>
<MediaComponent
label="Feature Image"
description="Add a feature image for your post"
{...form.register('feature_image')}
/>
<GhostTags label="Tags" {...form.register('tags', { value: [] })} />
</>
);
};

export default withProvider({
postComment: PostComment.POST,
minimumCharacters: [],
SettingsComponent: GhostSettings,
CustomPreviewComponent: undefined,
dto: GhostDto,
checkValidity: undefined,
maximumCharacters: 100000,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
'use client';

import { FC, useCallback, useEffect, useState } from 'react';
import { ReactTags, Tag, TagSelected } from 'react-tag-autocomplete';
import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values';
import { useCustomProviderFunction } from '@gitroom/frontend/components/launches/helpers/use.custom.provider.function';

interface GhostTag {
value: string;
label: string;
}

export const GhostTags: FC<{
name: string;
label: string;
onChange: (event: {
target: {
value: string[];
name: string;
};
}) => void;
}> = (props) => {
const { name, label } = props;
const form = useSettings();
const { getValues } = useSettings();
const customFunc = useCustomProviderFunction();
const [suggestions, setSuggestions] = useState<GhostTag[]>([]);
const [tagValue, setTagValue] = useState<TagSelected[]>([]);

const onDelete = useCallback(
(tagIndex: number) => {
const modify = tagValue.filter((_, i) => i !== tagIndex);
setTagValue(modify);
form.setValue(
name,
modify.map((t) => String(t.label))
);
},
[tagValue, name, form]
);

const onAddition = useCallback(
(newTag: Tag) => {
const modify = [...tagValue, newTag];
setTagValue(modify);
form.setValue(
name,
modify.map((t) => String(t.label))
);
},
[tagValue, name, form]
);

useEffect(() => {
// Fetch existing tags from Ghost
customFunc.get('tags').then((data: GhostTag[]) => {
setSuggestions(data || []);
});

// Load existing values
const settings = getValues()[name];
if (settings && Array.isArray(settings)) {
setTagValue(settings.map((t: string) => ({ value: t, label: t })));
}
}, []);

return (
<div>
<div className="text-[14px] mb-[6px]">{label}</div>
<ReactTags
allowNew
suggestions={suggestions}
selected={tagValue}
onAdd={onAddition}
onDelete={onDelete}
placeholderText="Add a tag..."
/>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { PostComment } from '@gitroom/frontend/components/new-launch/providers/h
import WordpressProvider from '@gitroom/frontend/components/new-launch/providers/wordpress/wordpress.provider';
import ListmonkProvider from '@gitroom/frontend/components/new-launch/providers/listmonk/listmonk.provider';
import GmbProvider from '@gitroom/frontend/components/new-launch/providers/gmb/gmb.provider';
import GhostProvider from '@gitroom/frontend/components/new-launch/providers/ghost/ghost.provider';

export const Providers = [
{
Expand Down Expand Up @@ -143,6 +144,10 @@ export const Providers = [
identifier: 'gmb',
component: GmbProvider,
},
{
identifier: 'ghost',
component: GhostProvider,
},
];
export const ShowAllProviders = forwardRef((props, ref) => {
const { date, current, global, selectedIntegrations, allIntegrations } =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { ListmonkDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-sett
import { GmbSettingsDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/gmb.settings.dto';
import { FarcasterDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/farcaster.dto';
import { FacebookDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/facebook.dto';
import { GhostDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/ghost.dto';

export type ProviderExtension<T extends string, M> = { __type: T } & M;
export type AllProvidersSettings =
Expand All @@ -42,6 +43,7 @@ export type AllProvidersSettings =
| ProviderExtension<'gmb', GmbSettingsDto>
| ProviderExtension<'facebook', FacebookDto>
| ProviderExtension<'wrapcast', FarcasterDto>
| ProviderExtension<'ghost', GhostDto>
| ProviderExtension<'threads', None>
| ProviderExtension<'mastodon', None>
| ProviderExtension<'bluesky', None>
Expand Down Expand Up @@ -74,6 +76,7 @@ export const allProviders = (setEmpty?: any) => {
{ value: GmbSettingsDto, name: 'gmb' },
{ value: FarcasterDto, name: 'wrapcast' },
{ value: FacebookDto, name: 'facebook' },
{ value: GhostDto, name: 'ghost' },
{ value: setEmpty, name: 'threads' },
{ value: setEmpty, name: 'mastodon' },
{ value: setEmpty, name: 'bluesky' },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {
IsArray,
IsDefined,
IsEnum,
IsOptional,
IsString,
MinLength,
ValidateNested,
} from 'class-validator';
import { MediaDto } from '@gitroom/nestjs-libraries/dtos/media/media.dto';
import { Type } from 'class-transformer';

export enum GhostPostStatus {
PUBLISHED = 'published',
DRAFT = 'draft',
SCHEDULED = 'scheduled',
}

export class GhostDto {
@IsString()
@MinLength(1)
@IsDefined()
title: string;

@IsOptional()
@IsString()
slug?: string;

@IsEnum(GhostPostStatus)
@IsDefined()
status: GhostPostStatus;

@IsOptional()
@ValidateNested()
@Type(() => MediaDto)
feature_image?: MediaDto;

@IsOptional()
@IsArray()
@IsString({ each: true })
tags?: string[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { VkProvider } from '@gitroom/nestjs-libraries/integrations/social/vk.pro
import { WordpressProvider } from '@gitroom/nestjs-libraries/integrations/social/wordpress.provider';
import { ListmonkProvider } from '@gitroom/nestjs-libraries/integrations/social/listmonk.provider';
import { GmbProvider } from '@gitroom/nestjs-libraries/integrations/social/gmb.provider';
import { GhostProvider } from '@gitroom/nestjs-libraries/integrations/social/ghost.provider';

export const socialIntegrationList: SocialProvider[] = [
new XProvider(),
Expand Down Expand Up @@ -58,6 +59,7 @@ export const socialIntegrationList: SocialProvider[] = [
new HashnodeProvider(),
new WordpressProvider(),
new ListmonkProvider(),
new GhostProvider(),
// new MastodonCustomProvider(),
];

Expand Down
Loading