session based posting

This commit is contained in:
2025-02-21 12:02:20 +01:00
parent 2bae543492
commit 4291eeacbc
9 changed files with 106 additions and 36 deletions
-9
View File
@@ -1,9 +0,0 @@
'use client';
import * as React from 'react';
import { ThemeProvider as NextThemesProvider } from 'next-themes';
import { type ThemeProviderProps } from 'next-themes';
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
}
+1 -1
View File
@@ -28,7 +28,7 @@ export async function POST(req: NextRequest) {
{ status: 409 } { status: 409 }
); );
await database.users.insertOne({ email, password, name, platforms: [] }); await database.users.insertOne({ email, password, name, platforms: {} });
const sessionId = (await database.sessions.insertOne({ user: email })) const sessionId = (await database.sessions.insertOne({ user: email }))
.insertedId; .insertedId;
+1 -1
View File
@@ -1,6 +1,6 @@
import { MongoClient } from 'mongodb'; import { MongoClient } from 'mongodb';
import config from './env'; import config from './env';
import { Schedule, Session, User } from '@/utils'; import { Schedule, ScheduleRequest, Session, User } from '@/utils';
const client = new MongoClient(config.mongoUrl); const client = new MongoClient(config.mongoUrl);
+10 -3
View File
@@ -1,14 +1,21 @@
import { TwitterApi } from 'twitter-api-v2'; import { TwitterApi } from 'twitter-api-v2';
import config from '@/app/api/env'; import config from '@/app/api/env';
import { inspect } from 'util'; import { inspect } from 'util';
import { PostRequest } from '@/utils'; import { Post } from '@/utils';
import database from '../database'; import database from '../database';
import { format } from 'date-fns'; import { format } from 'date-fns';
import cron from 'node-cron'; import cron from 'node-cron';
import { ObjectId } from 'mongodb';
export default async function post({ platforms, content }: PostRequest) { export default async function post({ platforms, content, account }: Post) {
try { try {
for (const platform of platforms) { const user = await database.users.findOne({
_id: new ObjectId(account),
});
if (!user) return;
for (const platformKey of platforms) {
const platform = user.platforms[platformKey];
switch (platform.platform) { switch (platform.platform) {
// X / Twitter // X / Twitter
case 'x': case 'x':
+57 -6
View File
@@ -1,14 +1,39 @@
import { NextResponse, NextRequest } from 'next/server'; import { NextResponse, NextRequest } from 'next/server';
import database from '../database'; import database from '../database';
import { PostRequest, Schedule } from '@/utils'; import { PostRequest, ScheduleRequest } from '@/utils';
import post from './post'; import post from './post';
import { ObjectId } from 'mongodb'; import { ObjectId } from 'mongodb';
import { use } from 'react';
export async function POST(req: NextRequest) { export async function POST(req: NextRequest) {
const request: PostRequest = await req.json(); const { sessionId, content, platforms }: PostRequest = await req.json();
post(request); console.log(sessionId);
if (typeof sessionId !== 'string')
return NextResponse.json(
{
message: 'Invalid structure, required param `id=`',
},
{ status: 400 }
);
const session = await database.sessions.findOne({
_id: new ObjectId(sessionId),
});
if (!session)
return NextResponse.json(
{
message: 'Invalid session',
},
{ status: 404 }
);
post({
account: session.user,
content,
platforms,
});
return NextResponse.json( return NextResponse.json(
{ {
@@ -19,9 +44,35 @@ export async function POST(req: NextRequest) {
} }
export async function PUT(req: NextRequest) { export async function PUT(req: NextRequest) {
const request: Schedule = await req.json(); const { sessionId, scheduled, content, platforms }: ScheduleRequest =
await req.json();
database.schedules.insertOne(request); if (typeof sessionId !== 'string')
return NextResponse.json(
{
message: 'Invalid structure, required param `id=`',
},
{ status: 400 }
);
const session = await database.sessions.findOne({
_id: new ObjectId(sessionId),
});
if (!session)
return NextResponse.json(
{
message: 'Invalid session',
},
{ status: 404 }
);
database.schedules.insertOne({
account: session.user,
scheduled,
content,
platforms,
});
return NextResponse.json( return NextResponse.json(
{ {
+3 -2
View File
@@ -22,7 +22,7 @@ import { format, parse } from 'date-fns';
import PostDialog, { today } from './postDialog'; import PostDialog, { today } from './postDialog';
import axios from 'axios'; import axios from 'axios';
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import { Schedule } from '@/utils'; import { ScheduleRequest } from '@/utils';
function closestChild(children: any, clientX: number, clientY: number) { function closestChild(children: any, clientX: number, clientY: number) {
let closestElement = null; let closestElement = null;
@@ -59,7 +59,7 @@ function CalendarApp() {
useEffect(() => { useEffect(() => {
axios.get(`/api/posts/?id=${sessionId}`).then((response) => { axios.get(`/api/posts/?id=${sessionId}`).then((response) => {
for (const [id, sched] of ( for (const [id, sched] of (
response.data.schedules as Schedule[] response.data.schedules as ScheduleRequest[]
).entries()) { ).entries()) {
const date = parse( const date = parse(
sched.scheduled, sched.scheduled,
@@ -160,6 +160,7 @@ function CalendarApp() {
setEventCount(eventCount + 1); setEventCount(eventCount + 1);
}} }}
eventId={eventCount} eventId={eventCount}
sessionId={sessionId}
/> />
<ContextMenu> <ContextMenu>
<ContextMenuTrigger onContextMenu={handleDialog}> <ContextMenuTrigger onContextMenu={handleDialog}>
+6 -4
View File
@@ -25,7 +25,7 @@ import { Textarea } from '@/components/ui/textarea';
import { Label } from '@/components/ui/label'; import { Label } from '@/components/ui/label';
import { useState } from 'react'; import { useState } from 'react';
import axios from 'axios'; import axios from 'axios';
import { Schedule } from '@/utils'; import { PostRequest, ScheduleRequest } from '@/utils';
type PostDialogProps = { type PostDialogProps = {
newPostDialogOpen: boolean; newPostDialogOpen: boolean;
@@ -34,6 +34,7 @@ type PostDialogProps = {
setDate: (d: Date) => void; setDate: (d: Date) => void;
eventId: number; eventId: number;
setEvents: (e: CalendarEventExternal) => void; setEvents: (e: CalendarEventExternal) => void;
sessionId: string;
}; };
export const today = new Date(); export const today = new Date();
@@ -46,6 +47,7 @@ export default function PostDialog({
setDate, setDate,
setEvents: addEvent, setEvents: addEvent,
eventId, eventId,
sessionId,
}: PostDialogProps) { }: PostDialogProps) {
const [content, setContent] = useState(''); const [content, setContent] = useState('');
@@ -133,10 +135,10 @@ export default function PostDialog({
}); });
axios.put('http://localhost:3000/api/posts', { axios.put('http://localhost:3000/api/posts', {
scheduled: format(date, 'y-MM-dd hh:mm'), scheduled: format(date, 'y-MM-dd hh:mm'),
account: '', sessionId,
platforms: [], platforms: ['andjksds'],
content, content,
} satisfies Schedule); } satisfies ScheduleRequest);
setNewPostDialogOpen(false); setNewPostDialogOpen(false);
}} }}
+2 -2
View File
@@ -1,8 +1,9 @@
import type { Metadata } from 'next'; import type { Metadata } from 'next';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
import './globals.css'; import './globals.css';
import { ThemeProvider } from './ThemeProvider';
import { Toaster } from '@/components/ui/toaster'; import { Toaster } from '@/components/ui/toaster';
import { ThemeProvider, useTheme } from 'next-themes';
import ThemeToggle from '@/components/themeToggle';
export const metadata: Metadata = { export const metadata: Metadata = {
title: 'Create Next App', title: 'Create Next App',
@@ -24,7 +25,6 @@ export default function RootLayout({
> >
<ThemeProvider <ThemeProvider
attribute="class" attribute="class"
defaultTheme="dark"
enableSystem enableSystem
disableTransitionOnChange disableTransitionOnChange
> >
+26 -8
View File
@@ -1,4 +1,20 @@
import { ObjectId } from 'mongodb'; /*
Request types
*/
export interface PostRequest {
sessionId: string;
content: string;
platforms: string[];
}
export interface ScheduleRequest extends PostRequest {
scheduled: string;
}
/*
Database types
*/
export type PlatformKind = 'x' | 'linkedin'; export type PlatformKind = 'x' | 'linkedin';
@@ -8,20 +24,22 @@ export interface Platform {
secret: string; secret: string;
} }
export interface PostRequest { export type Platforms = { [key: string]: Platform };
account: string;
content: string;
platforms: Platform[];
}
export interface User { export interface User {
name: string; name: string;
email: string; email: string;
password: string; password: string;
platforms: Platform[]; platforms: Platforms;
} }
export interface Schedule extends PostRequest { export interface Post {
account: string;
content: string;
platforms: string[];
}
export interface Schedule extends Post {
scheduled: string; scheduled: string;
} }