Skip to content

Commit

Permalink
feat: timing
Browse files Browse the repository at this point in the history
  • Loading branch information
Nevo David committed Sep 20, 2024
1 parent 6de19e4 commit 3a785e1
Show file tree
Hide file tree
Showing 20 changed files with 801 additions and 177 deletions.
13 changes: 12 additions & 1 deletion apps/backend/src/api/routes/integrations.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { ApiTags } from '@nestjs/swagger';
import { GetUserFromRequest } from '@gitroom/nestjs-libraries/user/user.from.request';
import { NotEnoughScopesFilter } from '@gitroom/nestjs-libraries/integrations/integration.missing.scopes';
import { PostsService } from '@gitroom/nestjs-libraries/database/prisma/posts/posts.service';
import { IntegrationTimeDto } from '@gitroom/nestjs-libraries/dtos/integrations/integration.time.dto';

@ApiTags('Integrations')
@Controller('/integrations')
Expand Down Expand Up @@ -55,6 +56,7 @@ export class IntegrationsController {
inBetweenSteps: p.inBetweenSteps,
refreshNeeded: p.refreshNeeded,
type: p.type,
time: JSON.parse(p.postingTimes)
})),
};
}
Expand Down Expand Up @@ -97,6 +99,14 @@ export class IntegrationsController {
return { url };
}

@Post('/:id/time')
async setTime(
@GetOrgFromRequest() org: Organization,
@Param('id') id: string,
@Body() body: IntegrationTimeDto
) {
return this._integrationService.setTimes(org.id, id, body);
}
@Post('/function')
async functionIntegration(
@GetOrgFromRequest() org: Organization,
Expand Down Expand Up @@ -238,7 +248,8 @@ export class IntegrationsController {
expiresIn,
username,
integrationProvider.isBetweenSteps,
body.refresh
body.refresh,
+body.timezone
);
}

Expand Down
2 changes: 0 additions & 2 deletions apps/backend/src/api/routes/posts.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.reque
import { Organization, User } from '@prisma/client';
import { CreatePostDto } from '@gitroom/nestjs-libraries/dtos/posts/create.post.dto';
import { GetPostsDto } from '@gitroom/nestjs-libraries/dtos/posts/get.posts.dto';
import { CommentsService } from '@gitroom/nestjs-libraries/database/prisma/comments/comments.service';
import { StarsService } from '@gitroom/nestjs-libraries/database/prisma/stars/stars.service';
import { CheckPolicies } from '@gitroom/backend/services/auth/permissions/permissions.ability';
import {
Expand All @@ -30,7 +29,6 @@ import { CreateGeneratedPostsDto } from '@gitroom/nestjs-libraries/dtos/generato
export class PostsController {
constructor(
private _postsService: PostsService,
private _commentsService: CommentsService,
private _starsService: StarsService,
private _messagesService: MessagesService
) {}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { HttpStatusCode } from 'axios';

export const dynamic = 'force-dynamic';

import { internalFetch } from '@gitroom/helpers/utils/internal.fetch';
import { redirect } from 'next/navigation';

export default async function Page({
params: { provider },
searchParams,
}: {
params: { provider: string };
searchParams: any;
}) {
if (provider === 'x') {
searchParams = {
...searchParams,
state: searchParams.oauth_token || '',
code: searchParams.oauth_verifier || '',
refresh: searchParams.refresh || '',
};
}

const data = await internalFetch(`/integrations/social/${provider}/connect`, {
method: 'POST',
body: JSON.stringify(searchParams),
});

if (data.status === HttpStatusCode.NotAcceptable) {
return redirect(`/launches?scope=missing`);
}

const { inBetweenSteps, id } = await data.json();

if (inBetweenSteps && !searchParams.refresh) {
return redirect(`/launches?added=${provider}&continue=${id}`);
}

return redirect(`/launches?added=${provider}`);
}
Original file line number Diff line number Diff line change
@@ -1,40 +1,13 @@
import { HttpStatusCode } from 'axios';
import { IntegrationRedirectComponent } from '@gitroom/frontend/components/launches/integration.redirect.component';

export const dynamic = 'force-dynamic';

import { internalFetch } from '@gitroom/helpers/utils/internal.fetch';
import { redirect } from 'next/navigation';

export default async function Page({
params: { provider },
searchParams,
}: {
params: { provider: string };
searchParams: any;
}) {
if (provider === 'x') {
searchParams = {
...searchParams,
state: searchParams.oauth_token || '',
code: searchParams.oauth_verifier || '',
refresh: searchParams.refresh || '',
};
}

const data = await internalFetch(`/integrations/social/${provider}/connect`, {
method: 'POST',
body: JSON.stringify(searchParams),
});

if (data.status === HttpStatusCode.NotAcceptable) {
return redirect(`/launches?scope=missing`);
}

const { inBetweenSteps, id } = await data.json();

if (inBetweenSteps && !searchParams.refresh) {
return redirect(`/launches?added=${provider}&continue=${id}`);
}

return redirect(`/launches?added=${provider}`);
return <IntegrationRedirectComponent />;
}
13 changes: 13 additions & 0 deletions apps/frontend/src/app/(site)/integrations/social/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ReactNode } from 'react';

export default async function IntegrationLayout({
children,
}: {
children: ReactNode;
}) {
return (
<div className="text-6xl text-center mt-[50px]">
Adding channel, Redirecting You{children}
</div>
);
}
57 changes: 47 additions & 10 deletions apps/frontend/src/components/launches/add.edit.model.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import { useStateCallback } from '@gitroom/react/helpers/use.state.callback';
import { CopilotPopup } from '@copilotkit/react-ui';
import { useUser } from '@gitroom/frontend/components/layout/user.context';
import { makeId } from '@gitroom/nestjs-libraries/services/make.is';
import Image from 'next/image';

export const AddEditModal: FC<{
date: dayjs.Dayjs;
Expand Down Expand Up @@ -111,6 +112,8 @@ export const AddEditModal: FC<{
setSelectedIntegrations([
integrations.find((p) => p.id === existingData.integration)!,
]);
} else if (integrations.length === 1) {
setSelectedIntegrations([integrations[0]]);
}
}, [existingData.integration]);

Expand Down Expand Up @@ -279,7 +282,8 @@ export const AddEditModal: FC<{
) {
if (
!(await deleteDialog(
`${key?.integration?.name} post is too long, it will be cropped, do you want to continue?`, 'Yes, continue'
`${key?.integration?.name} post is too long, it will be cropped, do you want to continue?`,
'Yes, continue'
))
) {
await key.trigger();
Expand Down Expand Up @@ -381,7 +385,9 @@ export const AddEditModal: FC<{
instructions="You are an assistant that help the user to schedule their social media posts, everytime somebody write something, try to use a function call, if not prompt the user that the request is invalid and you are here to assists with social media posts"
/>
)}
<div className={clsx('flex p-[10px] rounded-[4px] bg-primary gap-[20px]')}>
<div
className={clsx('flex p-[10px] rounded-[4px] bg-primary gap-[20px]')}
>
<div
className={clsx(
'flex flex-col gap-[16px] transition-all duration-700 whitespace-nowrap',
Expand All @@ -402,14 +408,43 @@ export const AddEditModal: FC<{
</div>
</TopTitle>

{!existingData.integration && (
{!existingData.integration && integrations.length > 1 ? (
<PickPlatforms
integrations={integrations.filter((f) => !f.disabled)}
selectedIntegrations={[]}
singleSelect={false}
onChange={setSelectedIntegrations}
isMain={true}
/>
) : (
<div
className={clsx(
'relative w-[34px] h-[34px] rounded-full flex justify-center items-center bg-fifth filter transition-all duration-500',
)}
>
<Image
src={selectedIntegrations?.[0]?.picture}
className="rounded-full"
alt={selectedIntegrations?.[0]?.identifier}
width={32}
height={32}
/>
{selectedIntegrations?.[0]?.identifier === 'youtube' ? (
<img
src="/icons/platforms/youtube.svg"
className="absolute z-10 -bottom-[5px] -right-[5px]"
width={20}
/>
) : (
<Image
src={`/icons/platforms/${selectedIntegrations?.[0]?.identifier}.png`}
className="rounded-full absolute z-10 -bottom-[5px] -right-[5px] border border-fifth"
alt={selectedIntegrations?.[0]?.identifier}
width={20}
height={20}
/>
)}
</div>
)}
<div
id="renderEditor"
Expand All @@ -426,13 +461,15 @@ export const AddEditModal: FC<{
<Editor
order={index}
height={value.length > 1 ? 150 : 250}
commands={[
// ...commands
// .getCommands()
// .filter((f) => f.name === 'image'),
// newImage,
// postSelector(dateState),
]}
commands={
[
// ...commands
// .getCommands()
// .filter((f) => f.name === 'image'),
// newImage,
// postSelector(dateState),
]
}
value={p.content}
preview="edit"
// @ts-ignore
Expand Down
84 changes: 44 additions & 40 deletions apps/frontend/src/components/launches/calendar.context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,25 @@ import weekOfYear from 'dayjs/plugin/weekOfYear';
dayjs.extend(isoWeek);
dayjs.extend(weekOfYear);

const CalendarContext = createContext({
export const CalendarContext = createContext({
currentDay: dayjs().day() as 0 | 1 | 2 | 3 | 4 | 5 | 6,
currentWeek: dayjs().week(),
currentYear: dayjs().year(),
currentMonth: dayjs().month(),
comments: [] as Array<{ date: string; total: number }>,
integrations: [] as Integrations[],
trendings: [] as string[],
posts: [] as Array<Post & { integration: Integration }>,
reloadCalendarView: () => {/** empty **/},
reloadCalendarView: () => {
/** empty **/
},
display: 'week',
setFilters: (filters: {
currentWeek: number;
currentYear: number;
currentDay: 0 | 1 | 2 | 3 | 4 | 5 | 6;
currentMonth: number;
display: 'week' | 'month';
display: 'week' | 'month' | 'day';
}) => {
/** empty **/
},
Expand All @@ -53,6 +57,7 @@ export interface Integrations {
identifier: string;
type: string;
picture: string;
time: { time: number }[];
}

function getWeekNumber(date: Date) {
Expand Down Expand Up @@ -82,39 +87,37 @@ export const CalendarWeekProvider: FC<{
const [trendings] = useState<string[]>([]);
const searchParams = useSearchParams();

const display = searchParams.get('month') ? 'month' : 'week';
const display = searchParams.get('display') || 'week';

const [filters, setFilters] = useState({
currentWeek:
display === 'week'
? +(searchParams.get('week') || getWeekNumber(new Date()))
: 0,
currentMonth:
display === 'week' ? 0 : +(searchParams.get('month') || dayjs().month()),
currentDay: +(searchParams.get('day') || dayjs().day()) as
| 0
| 1
| 2
| 3
| 4
| 5
| 6,
currentWeek: +(searchParams.get('week') || getWeekNumber(new Date())),
currentMonth: +(searchParams.get('month') || dayjs().month()),
currentYear: +(searchParams.get('year') || dayjs().year()),
display,
});

const params = useMemo(() => {
return new URLSearchParams(
filters.currentWeek
? {
week: filters.currentWeek.toString(),
year: filters.currentYear.toString(),
}
: {
year: filters.currentYear.toString(),
month: (filters.currentMonth + 1).toString(),
}
).toString();
}, [filters]);

const loadData = useCallback(
async () => {
const data = (await fetch(`/posts?${params}`)).json();
return data;
},
[filters, params]
);
return new URLSearchParams({
display: filters.display,
day: filters.currentDay.toString(),
week: filters.currentWeek.toString(),
month: (filters.currentMonth + 1).toString(),
year: filters.currentYear.toString(),
}).toString();
}, [filters, display]);

const loadData = useCallback(async () => {
const data = (await fetch(`/posts?${params}`)).json();
return data;
}, [filters, params]);

const swr = useSWR(`/posts-${params}`, loadData, {
refreshInterval: 3600000,
Expand All @@ -125,22 +128,23 @@ export const CalendarWeekProvider: FC<{

const setFiltersWrapper = useCallback(
(filters: {
currentDay: 0 | 1 | 2 | 3 | 4 | 5 | 6;
currentWeek: number;
currentYear: number;
currentMonth: number;
display: 'week' | 'month';
display: 'week' | 'month' | 'day';
}) => {
setFilters(filters);
setInternalData([]);
window.history.replaceState(
null,
'',
`/launches?${
filters.currentWeek
? `week=${filters.currentWeek}`
: `month=${filters.currentMonth}`
}&year=${filters.currentYear}`
);

const path = [
`day=${filters.currentDay}`,
`week=${filters.currentWeek}`,
`month=${filters.currentMonth}`,
`year=${filters.currentYear}`,
`display=${filters.display}`,
].filter((f) => f);
window.history.replaceState(null, '', `/launches?${path.join('&')}`);
},
[filters, swr.mutate]
);
Expand Down
Loading

0 comments on commit 3a785e1

Please sign in to comment.