bug fixes for frontend when trying to npm run build

This commit is contained in:
michael 2025-10-08 16:47:14 -05:00
parent 1a1ed3048d
commit aafc4078ae
24 changed files with 63 additions and 63 deletions

Binary file not shown.

View file

@ -77,7 +77,7 @@ services:
redis:
condition: service_healthy
ports:
- "8000:8000"
- "8003:8000"
environment:
# App configuration
APP_ENV: ${APP_ENV:-dev}

View file

@ -1,4 +1,4 @@
import { ReactNode } from 'react';
import type { ReactNode } from 'react';
import { Navigate } from 'react-router-dom';
import { useAuthStore } from '../../lib/auth';

View file

@ -1,4 +1,4 @@
import { ReactNode } from 'react';
import type { ReactNode } from 'react';
import { useAuthStore } from '../../lib/auth';
import type { UserRole } from '../../types/api';

View file

@ -2,7 +2,6 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'
import { render, screen, waitFor } from '../../../test/utils'
import { RequireAuth } from '../RequireAuth'
import { useAuthStore } from '../../../lib/auth'
import { UserRole } from '../../../types/api'
import { createMockUser } from '../../../test/utils'
// Mock the auth store
@ -18,7 +17,6 @@ describe('RequireAuth', () => {
})
it('renders children when user is authenticated', () => {
const mockUser = createMockUser()
mockUseAuthStore.mockReturnValue({
isAuthenticated: true,
isLoading: false,

View file

@ -1,4 +1,5 @@
import React, { Component, ErrorInfo, ReactNode } from 'react';
import { Component } from 'react';
import type { ErrorInfo, ReactNode } from 'react';
interface Props {
children: ReactNode;

View file

@ -1,4 +1,5 @@
import { ReactNode, useState } from 'react';
import { useState } from 'react';
import type { ReactNode } from 'react';
import { Sidebar } from './Sidebar';
import { Navbar } from './Navbar';

View file

@ -1,5 +1,5 @@
import { useState, useCallback } from 'react';
import { useDropzone } from 'react-dropzone';
import { useDropzone, type FileRejection } from 'react-dropzone';
interface UploadDropzoneProps {
onFileSelect: (file: File) => void;
@ -16,7 +16,7 @@ export function UploadDropzone({
}: UploadDropzoneProps) {
const [error, setError] = useState<string | null>(null);
const onDrop = useCallback((acceptedFiles: File[], rejectedFiles: { file: File; errors: { code: string }[] }[]) => {
const onDrop = useCallback((acceptedFiles: File[], rejectedFiles: FileRejection[]) => {
setError(null);
if (rejectedFiles.length > 0) {

View file

@ -102,7 +102,7 @@ export function VideoWithCaptions({
const video = videoRef.current;
if (!video) return;
let timeoutId: number;
let timeoutId: ReturnType<typeof setTimeout>;
const handleTimeUpdate = () => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {

View file

@ -1,4 +1,5 @@
import { createContext, useContext, ReactNode, useCallback } from 'react';
import { createContext, useContext, useCallback } from 'react';
import type { ReactNode } from 'react';
import { useJobStatusWebSocket } from '../hooks/useJobStatusWebSocket';
import { useToastContext } from './ToastContext';
import { getStatusMessageConfig } from '../utils/jobStatusMessages';

View file

@ -1,4 +1,5 @@
import { createContext, useContext, ReactNode, useState, useCallback } from 'react';
import { createContext, useContext, useState, useCallback } from 'react';
import type { ReactNode } from 'react';
export interface NotificationItem {
id: string;

View file

@ -1,4 +1,5 @@
import { createContext, useContext, ReactNode } from 'react';
import { createContext, useContext } from 'react';
import type { ReactNode } from 'react';
import { useToast } from '../hooks/useToast';
import { useNotificationContext } from './NotificationContext';
import type { ToastMessage } from '../components/Toast/Toast';

View file

@ -1,7 +1,7 @@
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
import { renderHook, waitFor } from '@testing-library/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { ReactNode } from 'react'
import type { ReactNode } from 'react'
import {
useJobs,
useJob,

View file

@ -8,7 +8,7 @@ import type {
} from '../types/api';
// Query hooks
export function useJobs(filters?: { status?: string; mine?: boolean }, options?: { enabled?: boolean }) {
export function useJobs(filters?: { status?: string; mine?: boolean; page?: number; size?: number }, options?: { enabled?: boolean }) {
return useQuery({
queryKey: ['jobs', filters],
queryFn: () => apiClient.getJobs(filters),

View file

@ -48,7 +48,7 @@ export const useAuthStore = create<AuthState>((set) => ({
refreshAuth: async () => {
try {
const response = await apiClient.refresh();
await apiClient.refresh();
// Token refresh succeeded, but we don't have user info
// In a proper implementation, the refresh endpoint would return user data
// For now, we'll assume if refresh succeeds and we have existing user, we're authenticated

View file

@ -250,7 +250,7 @@ export function FinalDetail() {
language={language}
assets={assets}
jobId={id!}
audioUrl={downloads?.downloads?.[language]?.audio_description_mp3}
audioUrl={typeof downloads?.downloads?.[language] === 'object' ? downloads?.downloads?.[language]?.audio_description_mp3 : undefined}
/>
))}
</div>

View file

@ -32,7 +32,9 @@ export function QCDetail() {
const isProcessing = approveEnglishMutation.isPending || rejectJobMutation.isPending || updateVttMutation.isPending || adjustTimingMutation.isPending;
// Get video URL from downloads
const videoUrl = downloads?.downloads?.source_video || '';
const videoUrl = typeof downloads?.downloads?.source_video === 'string'
? downloads.downloads.source_video
: '';
// Load VTT content when fetched
useEffect(() => {

View file

@ -69,14 +69,16 @@ export function JobDetail() {
// Get video URL from downloads
const videoUrl = downloads?.downloads?.source_video || '';
const videoUrl = typeof downloads?.downloads?.source_video === 'string'
? downloads.downloads.source_video
: '';
const tabs = [
{ id: 'overview', label: 'Overview', icon: '📋' },
{ id: 'video', label: 'Video Preview', icon: '🎥', disabled: !videoUrl },
{ id: 'assets', label: 'Assets', icon: '📁' },
{ id: 'history', label: 'History', icon: '📜' },
] as const;
{ id: 'overview' as const, label: 'Overview', icon: '📋', disabled: false },
{ id: 'video' as const, label: 'Video Preview', icon: '🎥', disabled: !videoUrl },
{ id: 'assets' as const, label: 'Assets', icon: '📁', disabled: false },
{ id: 'history' as const, label: 'History', icon: '📜', disabled: false },
];
if (isLoading) {
return (
@ -182,8 +184,8 @@ export function JobDetail() {
{videoUrl ? (
<VideoWithCaptions
videoUrl={videoUrl}
captionsVtt={englishVtt?.captions_vtt}
audioDescriptionVtt={englishVtt?.audio_description_vtt}
captionsVtt={englishVtt?.captions_vtt || ''}
audioDescriptionVtt={englishVtt?.audio_description_vtt || ''}
/>
) : (
<div className="text-center py-8 text-gray-500">
@ -346,7 +348,7 @@ export function JobDetail() {
{job.error && (
<div className="bg-red-50 border border-red-200 rounded-lg p-4">
<h3 className="text-sm font-medium text-red-800 mb-2">Processing Error</h3>
<p className="text-xs text-red-600">{job.error.message}</p>
<p className="text-xs text-red-600">{String(job.error.message || 'Unknown error')}</p>
</div>
)}
</div>

View file

@ -105,13 +105,7 @@ export function NewJob() {
setValue('transcreation', transcreation.filter(l => l !== lang));
};
const toggleTranscreation = (lang: string) => {
if (transcreation.includes(lang)) {
setValue('transcreation', transcreation.filter(l => l !== lang));
} else {
setValue('transcreation', [...transcreation, lang]);
}
};
// Removed toggleTranscreation - not currently used
// Success state
if (createdJob) {

View file

@ -1,8 +1,9 @@
import { ReactElement } from 'react'
import { render, RenderOptions } from '@testing-library/react'
import type { ReactElement } from 'react'
import { render } from '@testing-library/react'
import type { RenderOptions } from '@testing-library/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { BrowserRouter } from 'react-router-dom'
import { User, UserRole } from '../types/api'
import type { User, UserRole } from '../types/api'
// Mock user for testing
export const createMockUser = (overrides: Partial<User> = {}): User => ({

View file

@ -139,7 +139,4 @@ export interface BulkDeleteResponse {
export interface JobDeleteResponse {
message: string;
}
// Ensure Job is properly exported
export type { Job };
}

View file

@ -23,5 +23,6 @@
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["src"]
"include": ["src"],
"exclude": ["src/**/*.test.ts", "src/**/*.test.tsx", "src/test"]
}

View file

@ -3,7 +3,7 @@
# Frontend Build and Deploy Script
# =============================================================================
# Builds the React frontend and deploys to Apache document root
# Run from: /opt/accessible-video/
# Run from: /opt/video-accessibility/
# Usage: ./scripts/build-frontend.sh
# =============================================================================
@ -17,7 +17,7 @@ BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
PROJECT_DIR="/opt/accessible-video"
PROJECT_DIR="/opt/video-accessibility"
FRONTEND_DIR="$PROJECT_DIR/frontend"
DEPLOY_DIR="/var/www/html/video-accessibility"
@ -100,9 +100,9 @@ build_frontend() {
cd "$FRONTEND_DIR"
# Install dependencies
# Install dependencies (including dev dependencies needed for build)
print_info "Installing dependencies..."
npm ci --only=production
npm ci
print_success "Dependencies installed"
# Build the application

View file

@ -3,7 +3,7 @@
# Deployment Script for Accessible Video Platform
# =============================================================================
# This script handles building and deploying the application
# Run from: /opt/accessible-video/
# Run from: /opt/video-accessibility/
# Usage: ./scripts/deploy.sh [options]
# =============================================================================
@ -17,7 +17,7 @@ BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
PROJECT_DIR="/opt/accessible-video"
PROJECT_DIR="/opt/video-accessibility"
COMPOSE_FILES="-f docker-compose.yml -f docker-compose.prod.yml"
# =============================================================================
@ -39,7 +39,7 @@ print_error() {
}
print_warning() {
echo -e "${YELLOW}  $1${NC}"
echo -e "${YELLOW}<EFBFBD> $1${NC}"
}
print_info() {
@ -55,7 +55,7 @@ preflight_checks() {
# Check if running from correct directory
if [ ! -f "docker-compose.yml" ]; then
print_error "docker-compose.yml not found. Please run from /opt/accessible-video/"
print_error "docker-compose.yml not found. Please run from /opt/video-accessibility/"
exit 1
fi
print_success "Running from correct directory"
@ -88,12 +88,12 @@ preflight_checks() {
fi
print_success "Docker is running"
# Check if docker-compose is available
if ! command -v docker-compose &> /dev/null; then
print_error "docker-compose is not installed"
# Check if docker compose is available
if ! docker compose version &> /dev/null; then
print_error "docker compose is not installed"
exit 1
fi
print_success "docker-compose is available"
print_success "docker compose is available"
echo ""
}
@ -142,17 +142,17 @@ deploy_backend() {
# Build images
print_info "Building Docker images (this may take a few minutes)..."
docker-compose $COMPOSE_FILES build --no-cache
docker compose $COMPOSE_FILES build --no-cache
print_success "Docker images built"
# Stop existing containers
print_info "Stopping existing containers..."
docker-compose $COMPOSE_FILES down
docker compose $COMPOSE_FILES down
print_success "Containers stopped"
# Start services
print_info "Starting services..."
docker-compose $COMPOSE_FILES up -d
docker compose $COMPOSE_FILES up -d
print_success "Services started"
# Wait for services to be healthy
@ -160,9 +160,9 @@ deploy_backend() {
sleep 10
# Check service health
if docker-compose $COMPOSE_FILES ps | grep -q "unhealthy"; then
if docker compose $COMPOSE_FILES ps | grep -q "unhealthy"; then
print_error "Some services are unhealthy!"
docker-compose $COMPOSE_FILES ps
docker compose $COMPOSE_FILES ps
exit 1
fi
print_success "All services are healthy"
@ -217,7 +217,7 @@ run_migrations() {
print_header "Running Database Migrations"
print_info "Running migrations..."
docker-compose $COMPOSE_FILES exec -T api python migrate.py
docker compose $COMPOSE_FILES exec -T api python migrate.py
print_success "Migrations completed"
echo ""
@ -231,7 +231,7 @@ display_status() {
print_header "Deployment Status"
echo -e "${BLUE}Container Status:${NC}"
docker-compose $COMPOSE_FILES ps
docker compose $COMPOSE_FILES ps
echo ""
echo -e "${BLUE}Service URLs:${NC}"
@ -243,10 +243,10 @@ display_status() {
echo -e "${GREEN}Deployment completed successfully!${NC}"
echo ""
echo "To view logs:"
echo " docker-compose $COMPOSE_FILES logs -f [service]"
echo " docker compose $COMPOSE_FILES logs -f [service]"
echo ""
echo "To restart a service:"
echo " docker-compose $COMPOSE_FILES restart [service]"
echo " docker compose $COMPOSE_FILES restart [service]"
echo ""
}