use dioxus::prelude::*;
use dioxus_free_icons::{Icon, icons::ld_icons::*};
use crate::parser::ApiResponse;
use super::schema_viewer::SchemaViewer;
#[derive(Props, Clone, PartialEq)]
pub struct ResponsesListProps {
pub responses: Vec<ApiResponse>,
}
#[component]
pub fn ResponsesList(props: ResponsesListProps) -> Element {
if props.responses.is_empty() {
return rsx! {};
}
rsx! {
div { class: "space-y-2",
for response in &props.responses {
ResponseItem { key: "{response.status_code}", response: response.clone() }
}
}
}
}
#[derive(Props, Clone, PartialEq)]
pub struct ResponseItemProps {
pub response: ApiResponse,
}
#[component]
pub fn ResponseItem(props: ResponseItemProps) -> Element {
let mut is_expanded = use_signal(|| false);
let response = &props.response;
let badge_class = response.status_badge_class();
let has_content = !response.content.is_empty();
rsx! {
div { class: "border border-base-300 rounded-lg overflow-hidden",
button {
class: "w-full flex items-center gap-3 px-3 py-2 text-left hover:bg-base-200 transition-colors",
disabled: !has_content,
onclick: move |_| {
if has_content {
is_expanded.set(!is_expanded());
}
},
if has_content {
Icon {
class: if is_expanded() { "size-4 text-base-content/50 transform rotate-90 transition-transform" } else { "size-4 text-base-content/50 transition-transform" },
icon: LdChevronRight
}
}
span { class: "badge {badge_class} badge-sm font-mono font-bold",
"{response.status_code}"
}
span { class: "text-sm text-base-content/70 flex-1",
"{response.description}"
}
}
if is_expanded() && has_content {
div { class: "border-t border-base-300 bg-base-200/30",
for content in &response.content {
div { class: "p-3",
div { class: "mb-2",
code { class: "text-xs font-mono text-base-content/50",
"{content.media_type}"
}
}
if let Some(schema) = &content.schema {
SchemaViewer {
schema: schema.clone(),
expanded: true,
}
}
if let Some(example) = &content.example {
div { class: "mt-3 p-2 bg-base-300 rounded",
span { class: "text-xs text-base-content/50 font-semibold", "Example" }
pre { class: "mt-1 text-xs font-mono text-secondary overflow-x-auto whitespace-pre-wrap",
"{example}"
}
}
}
}
}
}
}
}
}
}