feat: Complete remaining management pages (Applications, Articles, Monitoring)

Frontend Implementation:
- Applications page: OAuth app management with client ID/secret
  * Client secret regeneration with secure display
  * Redirect URI management with chip interface
  * Copy-to-clipboard for credentials

- Articles page: News articles browser with filters
  * Category, translation, and image status filters
  * Article detail modal with full content
  * Retry controls for failed translations/images
  * Server-side pagination support

- Monitoring page: System health and metrics dashboard
  * Real-time CPU, memory, and disk usage
  * Database statistics display
  * Services status monitoring
  * Recent logs table with level filtering
  * Auto-refresh toggle (30s interval)

All pages follow the established DataGrid + MainLayout pattern with:
- Consistent UI/UX across all management pages
- Material-UI components and styling
- Error handling and loading states
- Full API integration with backend endpoints

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
jungwoo choi
2025-11-04 22:00:13 +09:00
parent a9024ef9a1
commit d6ae03f42b
6 changed files with 1416 additions and 0 deletions

View File

@ -0,0 +1,33 @@
import apiClient from './client'
import type { Article, ArticleFilter, PaginatedResponse } from '@/types'
export const getArticles = async (
filters?: ArticleFilter & { skip?: number; limit?: number }
): Promise<PaginatedResponse<Article>> => {
const response = await apiClient.get<PaginatedResponse<Article>>('/api/v1/articles/', {
params: filters,
})
return response.data
}
export const getArticle = async (articleId: string): Promise<Article> => {
const response = await apiClient.get<Article>(`/api/v1/articles/${articleId}`)
return response.data
}
export const deleteArticle = async (articleId: string): Promise<{ message: string }> => {
const response = await apiClient.delete<{ message: string }>(`/api/v1/articles/${articleId}`)
return response.data
}
export const retryTranslation = async (articleId: string): Promise<Article> => {
const response = await apiClient.post<Article>(`/api/v1/articles/${articleId}/retry-translation`)
return response.data
}
export const retryImageGeneration = async (articleId: string): Promise<Article> => {
const response = await apiClient.post<Article>(
`/api/v1/articles/${articleId}/retry-image-generation`
)
return response.data
}