fix: remove duplicate endpoints.ts, fix Login imports
- Remove web/src/api/endpoints.ts (redundant with index.ts) - Fix Login.tsx to use useLogin hook - Simplify Dockerfile (use CI-built artifacts)
This commit is contained in:
+3
-23
@@ -1,28 +1,8 @@
|
||||
# Build stage
|
||||
FROM node:22-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install pnpm
|
||||
RUN corepack enable && corepack prepare pnpm@9 --activate
|
||||
|
||||
# Copy package files
|
||||
COPY web/package.json web/pnpm-lock.yaml ./
|
||||
|
||||
# Install dependencies
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Copy source
|
||||
COPY web/ ./
|
||||
|
||||
# Build
|
||||
RUN pnpm build
|
||||
|
||||
# Production stage
|
||||
# Production stage - only needs nginx and built files
|
||||
FROM nginx:alpine
|
||||
|
||||
# Copy built files
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
# Copy built files (from CI artifact or local build)
|
||||
COPY web/dist /usr/share/nginx/html
|
||||
|
||||
# Copy nginx config
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
import { request } from './index'
|
||||
import type { MonitorStats, Task, Script, EnvVar, LogEntry, InterconnectNode, User, Settings } from './types'
|
||||
|
||||
// Auth
|
||||
export const login = (username: string, password: string) =>
|
||||
request<{ token: string }>('/auth/login', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ username, password })
|
||||
})
|
||||
|
||||
export const logout = () => request<void>('/auth/logout', { method: 'POST' })
|
||||
export const getCurrentUser = () => request<User>('/auth/me')
|
||||
|
||||
// Dashboard
|
||||
export const getStats = () => request<MonitorStats>('/stats')
|
||||
export const getSentence = () => request<{ content: string; author: string }>('/sentence')
|
||||
export const getTaskStats = () => request<{ total: number; running: number; scheduled: number }>('/taskstats')
|
||||
|
||||
// Tasks
|
||||
export const getTasks = (params?: { status?: string; tag?: string }) => {
|
||||
const query = new URLSearchParams(params as any).toString()
|
||||
return request<Task[]>(`/tasks${query ? '?' + query : ''}`)
|
||||
}
|
||||
|
||||
export const getTask = (id: number) => request<Task>(`/tasks/${id}`)
|
||||
export const createTask = (data: Partial<Task>) => request<Task>('/tasks', { method: 'POST', body: JSON.stringify(data) })
|
||||
export const updateTask = (id: number, data: Partial<Task>) => request<Task>(`/tasks/${id}`, { method: 'PUT', body: JSON.stringify(data) })
|
||||
export const deleteTask = (id: number) => request<void>(`/tasks/${id}`, { method: 'DELETE' })
|
||||
export const executeTask = (id: number) => request<void>(`/execute/task/${id}`, { method: 'POST' })
|
||||
export const getTags = () => request<string[]>('/tasks/tags')
|
||||
|
||||
// Scripts
|
||||
export const getScripts = () => request<Script[]>('/scripts')
|
||||
export const getScript = (id: number) => request<Script>(`/scripts/${id}`)
|
||||
export const createScript = (data: Partial<Script>) => request<Script>('/scripts', { method: 'POST', body: JSON.stringify(data) })
|
||||
export const updateScript = (id: number, data: Partial<Script>) => request<Script>(`/scripts/${id}`, { method: 'PUT', body: JSON.stringify(data) })
|
||||
export const deleteScript = (id: number) => request<void>(`/scripts/${id}`, { method: 'DELETE' })
|
||||
|
||||
// Env
|
||||
export const getEnvs = () => request<EnvVar[]>('/env')
|
||||
export const getEnv = (id: number) => request<EnvVar>(`/env/${id}`)
|
||||
export const createEnv = (data: Partial<EnvVar>) => request<EnvVar>('/env', { method: 'POST', body: JSON.stringify(data) })
|
||||
export const updateEnv = (id: number, data: Partial<EnvVar>) => request<EnvVar>(`/env/${id}`, { method: 'PUT', body: JSON.stringify(data) })
|
||||
export const deleteEnv = (id: number) => request<void>(`/env/${id}`, { method: 'DELETE' })
|
||||
|
||||
// Logs
|
||||
export const getLogs = (params?: { task_id?: number; status?: string; page?: number }) => {
|
||||
const query = new URLSearchParams(params as any).toString()
|
||||
return request<LogEntry[]>(`/logs${query ? '?' + query : ''}`)
|
||||
}
|
||||
|
||||
// Interconnect
|
||||
export const getNodes = () => request<InterconnectNode[]>('/interconnect/nodes')
|
||||
export const getNode = (id: string) => request<InterconnectNode>(`/interconnect/nodes/${id}`)
|
||||
export const createNode = (data: Partial<InterconnectNode>) => request<InterconnectNode>('/interconnect/nodes', { method: 'POST', body: JSON.stringify(data) })
|
||||
export const updateNode = (id: string, data: Partial<InterconnectNode>) => request<InterconnectNode>(`/interconnect/nodes/${id}`, { method: 'PUT', body: JSON.stringify(data) })
|
||||
export const deleteNode = (id: string) => request<void>(`/interconnect/nodes/${id}`, { method: 'DELETE' })
|
||||
|
||||
// Settings
|
||||
export const getSettings = () => request<Settings>('/settings')
|
||||
export const updateSettings = (data: Partial<Settings>) => request<Settings>('/settings', { method: 'PUT', body: JSON.stringify(data) })
|
||||
|
||||
// Monitor
|
||||
export const getMonitor = () => request<MonitorStats>('/monitor')
|
||||
+7
-10
@@ -1,27 +1,24 @@
|
||||
import { useState } from 'react'
|
||||
import { useNavigate } from '@tanstack/react-router'
|
||||
import { login } from '@/api/endpoints'
|
||||
import { useLogin } from '@/api/hooks'
|
||||
import { Lock, User, AlertCircle } from 'lucide-react'
|
||||
|
||||
export default function Login() {
|
||||
const navigate = useNavigate()
|
||||
const loginMutation = useLogin()
|
||||
const [username, setUsername] = useState('')
|
||||
const [password, setPassword] = useState('')
|
||||
const [error, setError] = useState('')
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
setError('')
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
await login(username, password)
|
||||
await loginMutation.mutateAsync({ username, password })
|
||||
navigate({ to: '/' })
|
||||
} catch (err: any) {
|
||||
setError(err.message || 'Login failed')
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +127,7 @@ export default function Login() {
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={loading}
|
||||
disabled={loginMutation.isPending}
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: 12,
|
||||
@@ -140,11 +137,11 @@ export default function Login() {
|
||||
color: 'white',
|
||||
fontSize: 14,
|
||||
fontWeight: 500,
|
||||
cursor: loading ? 'not-allowed' : 'pointer',
|
||||
opacity: loading ? 0.7 : 1,
|
||||
cursor: loginMutation.isPending ? 'not-allowed' : 'pointer',
|
||||
opacity: loginMutation.isPending ? 0.7 : 1,
|
||||
}}
|
||||
>
|
||||
{loading ? 'Signing in...' : 'Sign In'}
|
||||
{loginMutation.isPending ? 'Signing in...' : 'Sign In'}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user