fix: remove duplicate endpoints.ts, fix Login imports
Build and Deploy / build (push) Failing after 10s
Build and Deploy / docker (push) Has been skipped
Build and Deploy / deploy (push) Has been skipped

- 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:
2026-07-20 20:00:41 +00:00
parent 6ffa2ecdfb
commit c3e834a2b4
3 changed files with 10 additions and 97 deletions
+3 -23
View File
@@ -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
-64
View File
@@ -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
View File
@@ -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>