207 lines
7.2 KiB
Vue

<script setup>
import RequestBuilder from '~/components/api-platform/RequestBuilder.vue'
import ResponseViewer from '~/components/api-platform/ResponseViewer.vue'
import CollectionsSidebar from '~/components/api-platform/CollectionsSidebar.vue'
import EnvironmentSelector from '~/components/api-platform/EnvironmentSelector.vue'
import SaveRequestModal from '~/components/api-platform/SaveRequestModal.vue'
import CodeGenerationModal from '~/components/api-platform/CodeGenerationModal.vue'
import ImportExportModal from '~/components/api-platform/ImportExportModal.vue'
import TestScriptsModal from '~/components/api-platform/TestScriptsModal.vue'
definePageMeta({
title: "API Platform",
middleware: ["auth"],
requiresAuth: true,
});
// Use composables for state management
const {
notifications,
dismissNotification,
showCollectionSidebar,
showSaveRequestModal
} = useApiPlatform()
// Add modal states
const showCodeGenerationModal = ref(false)
const showImportExportModal = ref(false)
const showTestScriptsModal = ref(false)
</script>
<template>
<div class="min-h-screen flex flex-col bg-gray-50 dark:bg-gray-900">
<!-- Enhanced Top Bar -->
<div class="bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 shadow-sm flex-shrink-0">
<div class="px-6 py-4">
<div class="flex items-center justify-between">
<div class="flex items-center gap-4">
<button
@click="showCollectionSidebar = !showCollectionSidebar"
class="flex items-center justify-center p-2.5 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors group"
:title="showCollectionSidebar ? 'Hide Collections' : 'Show Collections'"
>
<Icon
name="ph:sidebar"
size="20"
class="text-gray-600 dark:text-gray-400 group-hover:text-gray-900 dark:group-hover:text-gray-100 transition-colors"
/>
</button>
<h2 class="text-xl font-normal text-gray-300 dark:text-white">|</h2>
<div class="flex items-center gap-3">
<h1 class="text-xl font-semibold text-gray-900 dark:text-white">API Platform</h1>
</div>
</div>
<!-- Enhanced Action Bar -->
<div class="flex items-center gap-3">
<EnvironmentSelector />
<div class="h-6 w-px bg-gray-300 dark:bg-gray-600"></div>
<!-- Test Scripts Button -->
<rs-button
variant="secondary-outline"
size="sm"
@click="showTestScriptsModal = true"
class="flex items-center gap-2"
>
<Icon name="ic:outline-quiz" size="16" />
Tests
</rs-button>
<!-- Import/Export Button -->
<rs-button
variant="secondary-outline"
size="sm"
@click="showImportExportModal = true"
class="flex items-center gap-2"
>
<Icon name="ic:outline-import-export" size="16" />
Import/Export
</rs-button>
<!-- Code Generation Button -->
<rs-button
variant="secondary-outline"
size="sm"
@click="showCodeGenerationModal = true"
class="flex items-center gap-2"
>
<Icon name="ic:outline-code" size="16" />
Code
</rs-button>
<!-- Save Button -->
<rs-button
variant="secondary-outline"
size="sm"
@click="showSaveRequestModal = true"
class="flex items-center gap-2"
>
<Icon name="ic:outline-save" size="16" />
Save
</rs-button>
</div>
</div>
</div>
</div>
<div class="flex-1 flex">
<!-- Collections Sidebar with enhanced styling -->
<Transition
enter-active-class="transition ease-out duration-200"
enter-from-class="transform -translate-x-full"
enter-to-class="transform translate-x-0"
leave-active-class="transition ease-in duration-150"
leave-from-class="transform translate-x-0"
leave-to-class="transform -translate-x-full"
>
<CollectionsSidebar
v-if="showCollectionSidebar"
@close="showCollectionSidebar = false"
class="relative z-10 flex-shrink-0"
/>
</Transition>
<!-- Main Content Area -->
<div class="flex-1 flex flex-col min-w-0">
<!-- Request Builder -->
<div class="flex-shrink-0">
<RequestBuilder />
</div>
<!-- Response Section -->
<div class="flex-1">
<ResponseViewer />
</div>
</div>
</div>
<!-- Save Request Modal -->
<SaveRequestModal
v-if="showSaveRequestModal"
@close="showSaveRequestModal = false"
/>
<!-- Code Generation Modal -->
<CodeGenerationModal
v-if="showCodeGenerationModal"
@close="showCodeGenerationModal = false"
/>
<!-- Import/Export Modal -->
<ImportExportModal
v-if="showImportExportModal"
@close="showImportExportModal = false"
/>
<!-- Test Scripts Modal -->
<TestScriptsModal
v-if="showTestScriptsModal"
@close="showTestScriptsModal = false"
/>
<!-- Enhanced Notification System -->
<div class="fixed top-4 right-4 z-50 space-y-3 max-w-sm">
<TransitionGroup
enter-active-class="transform ease-out duration-300 transition"
enter-from-class="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2"
enter-to-class="translate-y-0 opacity-100 sm:translate-x-0"
leave-active-class="transition ease-in duration-100"
leave-from-class="opacity-100"
leave-to-class="opacity-0"
>
<div
v-for="notification in notifications"
:key="notification.id"
class="flex items-start gap-3 p-4 rounded-lg shadow-lg border backdrop-blur-sm transition-all duration-300 ease-in-out"
:class="{
'bg-green-50/90 border-green-200 text-green-800 dark:bg-green-900/90 dark:border-green-700 dark:text-green-200': notification.type === 'success',
'bg-red-50/90 border-red-200 text-red-800 dark:bg-red-900/90 dark:border-red-700 dark:text-red-200': notification.type === 'error',
'bg-blue-50/90 border-blue-200 text-blue-800 dark:bg-blue-900/90 dark:border-blue-700 dark:text-blue-200': notification.type === 'info',
'bg-yellow-50/90 border-yellow-200 text-yellow-800 dark:bg-yellow-900/90 dark:border-yellow-700 dark:text-yellow-200': notification.type === 'warning'
}"
>
<Icon
:name="
notification.type === 'success' ? 'ic:outline-check-circle' :
notification.type === 'error' ? 'ic:outline-error' :
notification.type === 'warning' ? 'ic:outline-warning' :
'ic:outline-info'
"
size="20"
class="flex-shrink-0 mt-0.5"
/>
<span class="text-sm font-medium flex-1 leading-relaxed">{{ notification.message }}</span>
<rs-button
variant="text"
size="sm"
@click="dismissNotification(notification.id)"
class="flex-shrink-0 opacity-70 hover:opacity-100 transition-opacity"
>
<Icon name="ic:outline-close" size="16" />
</rs-button>
</div>
</TransitionGroup>
</div>
</div>
</template>