import React, { useState, useEffect } from 'react'; import { Link, useNavigate } from 'react-router-dom'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { apiClient, type RouteRequest, type Feed, type PlatformChannel } from '../../../lib/api'; const RouteStep: React.FC = () => { const navigate = useNavigate(); const queryClient = useQueryClient(); const [formData, setFormData] = useState({ feed_id: 0, platform_channel_id: 0, priority: 50 }); const [errors, setErrors] = useState>({}); // Get onboarding options (feeds and channels) const { data: options, isLoading: optionsLoading } = useQuery({ queryKey: ['onboarding-options'], queryFn: () => apiClient.getOnboardingOptions() }); // Fetch existing routes to pre-fill form when going back const { data: routes } = useQuery({ queryKey: ['routes'], queryFn: () => apiClient.getRoutes(), retry: false, }); // Pre-fill form with existing data useEffect(() => { if (routes && routes.length > 0) { const firstRoute = routes[0]; setFormData({ feed_id: firstRoute.feed_id || 0, platform_channel_id: firstRoute.platform_channel_id || 0, priority: firstRoute.priority || 50 }); } }, [routes]); const createRouteMutation = useMutation({ mutationFn: (data: RouteRequest) => apiClient.createRouteForOnboarding(data), onSuccess: () => { // Invalidate onboarding status cache to refresh the status queryClient.invalidateQueries({ queryKey: ['onboarding-status'] }); queryClient.invalidateQueries({ queryKey: ['dashboard-stats'] }); navigate('/onboarding/complete'); }, onError: (error: any) => { if (error.response?.data?.errors) { setErrors(error.response.data.errors); } else { setErrors({ general: [error.response?.data?.message || 'An error occurred'] }); } } }); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); setErrors({}); createRouteMutation.mutate(formData); }; const handleChange = (field: keyof RouteRequest, value: string | number | Record) => { setFormData(prev => ({ ...prev, [field]: value })); // Clear field error when user starts typing if (errors[field]) { setErrors(prev => ({ ...prev, [field]: [] })); } }; if (optionsLoading) { return
Loading...
; } return (

Create Your First Route

Connect your feed to a channel by creating a route. This tells FFR which articles to post where.

{/* Progress indicator */}
4
5
{errors.general && (

{errors.general[0]}

)}
{errors.feed_id && (

{errors.feed_id[0]}

)}
{(!options?.platform_channels || options.platform_channels.length === 0) && (

No channels available. Please create a channel first.

)} {errors.platform_channel_id && (

{errors.platform_channel_id[0]}

)}
handleChange('priority', parseInt(e.target.value))} placeholder="50" className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" />

Higher priority routes are processed first (default: 50)

{errors.priority && (

{errors.priority[0]}

)}
← Back
); }; export default RouteStep;