selectable platform

This commit is contained in:
2025-03-04 18:03:02 +01:00
parent 1f73da7be6
commit 05a94d7192
4 changed files with 194 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
import config from '@/lib/config';
import { Platform } from '@/lib/types';
import { TwitterApi } from 'twitter-api-v2';
export default async function getPlatformIcon(platform: Platform) {
switch (platform.platform) {
case 'x':
const twitterClient = new TwitterApi({
appKey: config.twitter.key,
appSecret: config.twitter.secret,
accessToken: platform.token,
accessSecret: platform.secret,
});
const user = await twitterClient.v1.verifyCredentials();
return user.profile_image_url_https;
default:
return null;
}
}
+67
View File
@@ -0,0 +1,67 @@
import { NextResponse, NextRequest } from 'next/server';
import database from '../../../lib/database';
import {
PlatformKind,
Platforms,
PostRequest,
ScheduleRequest,
UserPlatforms,
} from '@/lib/types';
import { ObjectId } from 'mongodb';
import { HttpStatusCode } from 'axios';
import getPlatformIcon from './getPlatformIcon';
export async function GET(req: NextRequest) {
const sessionId = req.cookies.get('session_id');
if (!sessionId)
return NextResponse.json(
{
message: 'No session',
},
{ status: HttpStatusCode.Unauthorized }
);
const session = await database.sessions.findOne({
_id: new ObjectId(sessionId.value),
});
if (!session)
return NextResponse.json(
{
message: 'Invalid session',
},
{ status: HttpStatusCode.NotFound }
);
const user = await database.users.findOne({
_id: new ObjectId(session.user),
});
if (!user)
return NextResponse.json(
{
message: 'User not found',
},
{ status: HttpStatusCode.NotFound }
);
const platforms: UserPlatforms = {};
for (const [name, platform] of Object.entries(user.platforms)) {
const icon = await getPlatformIcon(platform);
if (!icon) continue;
platforms[name] = {
...platform,
icon,
};
}
return NextResponse.json(
{
message: 'ok',
platforms,
},
{ status: HttpStatusCode.Ok }
);
}
+61
View File
@@ -0,0 +1,61 @@
"use client"
import * as React from "react"
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group"
import { type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
import { toggleVariants } from "@/components/ui/toggle"
const ToggleGroupContext = React.createContext<
VariantProps<typeof toggleVariants>
>({
size: "default",
variant: "default",
})
const ToggleGroup = React.forwardRef<
React.ElementRef<typeof ToggleGroupPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root> &
VariantProps<typeof toggleVariants>
>(({ className, variant, size, children, ...props }, ref) => (
<ToggleGroupPrimitive.Root
ref={ref}
className={cn("flex items-center justify-center gap-1", className)}
{...props}
>
<ToggleGroupContext.Provider value={{ variant, size }}>
{children}
</ToggleGroupContext.Provider>
</ToggleGroupPrimitive.Root>
))
ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName
const ToggleGroupItem = React.forwardRef<
React.ElementRef<typeof ToggleGroupPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> &
VariantProps<typeof toggleVariants>
>(({ className, children, variant, size, ...props }, ref) => {
const context = React.useContext(ToggleGroupContext)
return (
<ToggleGroupPrimitive.Item
ref={ref}
className={cn(
toggleVariants({
variant: context.variant || variant,
size: context.size || size,
}),
className
)}
{...props}
>
{children}
</ToggleGroupPrimitive.Item>
)
})
ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName
export { ToggleGroup, ToggleGroupItem }
+45
View File
@@ -0,0 +1,45 @@
"use client"
import * as React from "react"
import * as TogglePrimitive from "@radix-ui/react-toggle"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const toggleVariants = cva(
"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
{
variants: {
variant: {
default: "bg-transparent",
outline:
"border border-input bg-transparent shadow-sm hover:bg-accent hover:text-accent-foreground",
},
size: {
default: "h-9 px-2 min-w-9",
sm: "h-8 px-1.5 min-w-8",
lg: "h-10 px-2.5 min-w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
const Toggle = React.forwardRef<
React.ElementRef<typeof TogglePrimitive.Root>,
React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root> &
VariantProps<typeof toggleVariants>
>(({ className, variant, size, ...props }, ref) => (
<TogglePrimitive.Root
ref={ref}
className={cn(toggleVariants({ variant, size, className }))}
{...props}
/>
))
Toggle.displayName = TogglePrimitive.Root.displayName
export { Toggle, toggleVariants }