"use client";
import { useMockRequest } from "@/components/fumastudio/mock-request";
import { Schema } from "@/components/fumastudio/schema";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { HttpCode } from "@/lib/http-codes";
import {
AllSchema,
ApiKeyHeaderScheme,
ApiKeyQueryScheme,
BasicAuthScheme,
BearerAuthScheme,
ObjectSchema,
ReplySchema,
} from "@trythis/js-schema";
import { useEffect, useState } from "react";
export type AuthSchemes =
| BasicAuthScheme
| BearerAuthScheme
| ApiKeyHeaderScheme
| ApiKeyQueryScheme;
const AuthorizationScheme = (props: { schema: AuthSchemes[] }) => {
const [selectedAuth, setSelectedAuth] = useState(
props.schema?.[0]?.type || "",
);
const [selectedScheme, setSelectedScheme] = useState<AuthSchemes | null>(
null,
);
useEffect(() => {
if (props.schema && props.schema.length > 0) {
const item =
props.schema.find(
(item) => item.type === selectedAuth,
) || null;
setSelectedScheme(item);
}
}, [selectedAuth, props.schema]);
if (!props.schema) return;
return (
<>
<div className="flex flex-col w-full gap-y-4">
<div className="flex items-baseline border-b pb-2.5 border-gray-100 dark:border-gray-800 w-full">
<h4 className="flex-1 mb-0 font-inter text-[1.125em] leading-normal font-semibold">
Authorizations
</h4>
<div className="flex items-center font-mono text-xs gap-x-3">
<div className="px-2 py-0.5 font-medium text-gray-600 dark:text-gray-300 hover:text-zinc-950 dark:hover:text-white transition-all">
<Select
value={selectedAuth}
onValueChange={(v) =>
setSelectedAuth(
v as AuthSchemes["type"],
)
}>
<SelectTrigger className="h-8 text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent className="[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 ">
{props.schema &&
props.schema
.length > 0 &&
props.schema.map(
({
type,
}: AuthSchemes) => (
<SelectItem
key={
type
}
value={
type
}
className="text-xs">
{
type
}
</SelectItem>
),
)}
</SelectContent>
</Select>
</div>
</div>
</div>
</div>
{selectedScheme && (
<Schema
schema={selectedScheme}
depth={0}
path="authorization"
type="authorization"
/>
)}
</>
);
};
const QueryParamsSchema = (props: { schema: ObjectSchema }) => {
return (
<>
<div className="flex flex-col w-full gap-y-4">
<div className="flex items-baseline border-b pb-2.5 border-gray-100 dark:border-gray-800 w-full">
<h4 className="flex-1 mb-0 font-inter text-[1.125em] leading-normal font-semibold">
Query Parameters
</h4>
<div className="flex items-center"></div>
</div>
</div>
<Schema
schema={props.schema}
depth={0}
path="query"
type="query"
/>
</>
);
};
const PathParamsSchema = (props: { schema: ObjectSchema }) => {
return (
<>
<div className="flex flex-col w-full gap-y-4">
<div className="flex items-baseline border-b pb-2.5 border-gray-100 dark:border-gray-800 w-full">
<h4 className="flex-1 mb-0 font-inter text-[1.125em] leading-normal font-semibold">
Path Parameters
</h4>
<div className="flex items-center"></div>
</div>
</div>
<Schema
schema={props.schema}
depth={0}
path="parameter"
type="parameter"
/>
</>
);
};
const RequestBodySchema = (props: { schema: ObjectSchema }) => {
return (
<>
<div className="flex items-baseline border-b pb-2.5 border-gray-100 dark:border-gray-800 w-full">
<h4 className="flex-1 mb-0 font-inter text-[1.125em] leading-normal font-semibold">
Body
</h4>
<span className="px-2 py-0.5 font-mono text-xs font-medium text-gray-600 dark:text-gray-300 hover:text-gray-950 dark:hover:text-white">
application/json
</span>
</div>
<Schema
schema={props.schema}
depth={0}
path="body"
type="body"
/>
</>
);
};
type Properties = NonNullable<ReplySchema["properties"]>;
type ResponseBodySchemaProps = {
httpCodes: HttpCode[];
schema: ReplySchema;
};
const ResponseBodySchema = (props: ResponseBodySchemaProps) => {
const [code, setCode] = useState(String(props.httpCodes.at(0)?.status));
const [schema, setSchema] = useState<AllSchema | null>(null);
const { setResponseSlug } = useMockRequest();
useEffect(() => {
if (!props.httpCodes || !props.schema) return;
const status = props.httpCodes.find(
(http) => http.status === Number(code),
);
if (!status) {
console.log("Status not found: ", status);
return;
}
const schema = (props.schema?.properties as Properties)[
status.slug
];
if (schema) {
setResponseSlug(status.slug);
setSchema(schema);
}
}, [code]);
return (
<>
<div className="flex items-baseline border-b pb-2.5 border-gray-100 dark:border-gray-800 w-full">
<h4 className="flex-1 mb-0 font-inter text-[1.125em] leading-normal font-semibold">
Response
</h4>
<div className="flex items-center font-mono text-xs gap-x-3">
<div className="px-2 py-0.5 font-medium text-gray-600 dark:text-gray-300 hover:text-zinc-950 dark:hover:text-white transition-all">
<Select
value={code}
onValueChange={setCode}>
<SelectTrigger className="h-8 text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent className="[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 ">
{props.httpCodes.map(
({ slug, status }) => (
<SelectItem
key={slug}
value={String(
status,
)}
className="text-xs">
{status}
</SelectItem>
),
)}
</SelectContent>
</Select>
</div>
{schema && schema.contentType && (
<span className="px-2 py-0.5 font-medium text-gray-600 dark:text-gray-300 hover:text-gray-950 dark:hover:text-white">
{schema.contentType}
</span>
)}
</div>
</div>
<Schema
schema={schema!}
depth={0}
path="response"
type="response"
/>
</>
);
};
export {
AuthorizationScheme,
PathParamsSchema,
QueryParamsSchema,
RequestBodySchema,
ResponseBodySchema,
};