Added config file

This commit is contained in:
Tom Butcher 2025-06-01 00:18:15 +01:00
parent 6f65c062bd
commit 792d2e1c1c
42 changed files with 175 additions and 93 deletions

View File

@ -5,6 +5,7 @@ import { message, Modal, notification, Progress, Button, Space } from 'antd'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { ExclamationCircleOutlined } from '@ant-design/icons' import { ExclamationCircleOutlined } from '@ant-design/icons'
import InfoCircleIcon from '../Icons/InfoCircleIcon' import InfoCircleIcon from '../Icons/InfoCircleIcon'
import config from '../../config'
const AuthContext = createContext() const AuthContext = createContext()
@ -25,14 +26,14 @@ const AuthProvider = ({ children }) => {
setToken(null) setToken(null)
setExpiresAt(null) setExpiresAt(null)
setUserProfile(null) setUserProfile(null)
window.location.href = `http://localhost:8080/auth/logout?redirect_uri=${encodeURIComponent(redirectUri)}` window.location.href = `${config.backendUrl}/auth/logout?redirect_uri=${encodeURIComponent(redirectUri)}`
}, []) }, [])
// Login using query parameters // Login using query parameters
const loginWithSSO = useCallback( const loginWithSSO = useCallback(
(redirectUri = window.location.pathname + window.location.search) => { (redirectUri = window.location.pathname + window.location.search) => {
messageApi.info('Logging in with tombutcher.work') messageApi.info('Logging in with tombutcher.work')
window.location.href = `http://localhost:8080/auth/login?redirect_uri=${encodeURIComponent(redirectUri)}` window.location.href = `${config.backendUrl}/auth/login?redirect_uri=${encodeURIComponent(redirectUri)}`
}, },
[messageApi] [messageApi]
) )
@ -41,7 +42,7 @@ const AuthProvider = ({ children }) => {
setLoading(true) setLoading(true)
try { try {
// Make a call to your backend to check auth status // Make a call to your backend to check auth status
const response = await axios.get('http://localhost:8080/auth/user', { const response = await axios.get(`${config.backendUrl}/auth/user`, {
withCredentials: true // Important for including cookies withCredentials: true // Important for including cookies
}) })
@ -67,7 +68,7 @@ const AuthProvider = ({ children }) => {
const refreshToken = useCallback(async () => { const refreshToken = useCallback(async () => {
try { try {
const response = await axios.get('http://localhost:8080/auth/refresh', { const response = await axios.get(`${config.backendUrl}/auth/refresh`, {
withCredentials: true withCredentials: true
}) })
if (response.status === 200 && response.data) { if (response.status === 200 && response.data) {

View File

@ -28,6 +28,8 @@ import ReloadIcon from '../../Icons/ReloadIcon'
import FilamentStockState from '../common/FilamentStockState' import FilamentStockState from '../common/FilamentStockState'
import TimeDisplay from '../common/TimeDisplay' import TimeDisplay from '../common/TimeDisplay'
import config from '../../../config'
const { Text } = Typography const { Text } = Typography
const useStyle = createStyles(({ css, token }) => { const useStyle = createStyles(({ css, token }) => {
@ -65,7 +67,7 @@ const FilamentStocks = () => {
const fetchFilamentStocksData = useCallback(async () => { const fetchFilamentStocksData = useCallback(async () => {
try { try {
const response = await axios.get('http://localhost:8080/filamentstocks', { const response = await axios.get(`${config.backendUrl}/filamentstocks`, {
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'
}, },

View File

@ -22,6 +22,8 @@ import TimeDisplay from '../../common/TimeDisplay'
import FilamentIcon from '../../../Icons/FilamentIcon' import FilamentIcon from '../../../Icons/FilamentIcon'
import ReloadIcon from '../../../Icons/ReloadIcon' import ReloadIcon from '../../../Icons/ReloadIcon'
import config from '../../../../config'
const { Title } = Typography const { Title } = Typography
const FilamentStockInfo = () => { const FilamentStockInfo = () => {
@ -87,7 +89,7 @@ const FilamentStockInfo = () => {
try { try {
setFetchLoading(true) setFetchLoading(true)
const response = await axios.get( const response = await axios.get(
`http://localhost:8080/filamentStocks/${filamentStockId}`, `${config.backendUrl}/filamentStocks/${filamentStockId}`,
{ {
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'

View File

@ -15,6 +15,8 @@ import {
} from 'antd' } from 'antd'
import FilamentSelect from '../../common/FilamentSelect' import FilamentSelect from '../../common/FilamentSelect'
import config from '../../../../config'
const { Title } = Typography const { Title } = Typography
const initialNewFilamentStockForm = { const initialNewFilamentStockForm = {
@ -89,7 +91,7 @@ const NewFilamentStock = ({ onOk, reset }) => {
setNewFilamentStockLoading(true) setNewFilamentStockLoading(true)
try { try {
await axios.post( await axios.post(
`http://localhost:8080/filamentstocks`, `${config.backendUrl}/filamentstocks`,
newFilamentStockFormValues, newFilamentStockFormValues,
{ {
withCredentials: true // Important for including cookies withCredentials: true // Important for including cookies

View File

@ -16,6 +16,8 @@ import PlusIcon from '../../Icons/PlusIcon'
import ReloadIcon from '../../Icons/ReloadIcon' import ReloadIcon from '../../Icons/ReloadIcon'
import TimeDisplay from '../common/TimeDisplay' import TimeDisplay from '../common/TimeDisplay'
import config from '../../../config'
const { Text } = Typography const { Text } = Typography
const useStyle = createStyles(({ css, token }) => { const useStyle = createStyles(({ css, token }) => {
@ -50,7 +52,7 @@ const StockAudits = () => {
const fetchStockAuditsData = useCallback(async () => { const fetchStockAuditsData = useCallback(async () => {
try { try {
const response = await axios.get('http://localhost:8080/stockaudits', { const response = await axios.get(`${config.backendUrl}/stockaudits`, {
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'
}, },

View File

@ -23,6 +23,8 @@ import { AuthContext } from '../../../Auth/AuthContext'
import IdText from '../../common/IdText' import IdText from '../../common/IdText'
import TimeDisplay from '../../common/TimeDisplay' import TimeDisplay from '../../common/TimeDisplay'
import config from '../../../../config'
const { Text, Title } = Typography const { Text, Title } = Typography
const StockAuditInfo = () => { const StockAuditInfo = () => {
@ -46,7 +48,7 @@ const StockAuditInfo = () => {
try { try {
const response = await axios.get( const response = await axios.get(
`http://localhost:8080/stockaudits/${stockAuditId}`, `${config.backendUrl}/stockaudits/${stockAuditId}`,
{ {
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'

View File

@ -33,6 +33,8 @@ import CheckIcon from '../../Icons/CheckIcon'
import useColumnVisibility from '../hooks/useColumnVisibility' import useColumnVisibility from '../hooks/useColumnVisibility'
import TimeDisplay from '../common/TimeDisplay' import TimeDisplay from '../common/TimeDisplay'
import config from '../../../config'
const { Text } = Typography const { Text } = Typography
const useStyle = createStyles(({ css, token }) => { const useStyle = createStyles(({ css, token }) => {
@ -73,7 +75,7 @@ const Filaments = () => {
const fetchFilamentsData = useCallback( const fetchFilamentsData = useCallback(
async (pageNum = 1, append = false) => { async (pageNum = 1, append = false) => {
try { try {
const response = await axios.get('http://localhost:8080/filaments', { const response = await axios.get(`${config.backendUrl}/filaments`, {
params: { params: {
page: pageNum, page: pageNum,
limit: 25, limit: 25,

View File

@ -32,6 +32,8 @@ import TimeDisplay from '../../common/TimeDisplay.jsx'
import VendorSelect from '../../common/VendorSelect' import VendorSelect from '../../common/VendorSelect'
import useCollapseState from '../../hooks/useCollapseState' import useCollapseState from '../../hooks/useCollapseState'
import config from '../../../../config.js'
const { Title, Link } = Typography const { Title, Link } = Typography
const FilamentInfo = () => { const FilamentInfo = () => {
@ -81,7 +83,7 @@ const FilamentInfo = () => {
try { try {
setFetchLoading(true) setFetchLoading(true)
const response = await axios.get( const response = await axios.get(
`http://localhost:8080/filaments/${filamentId}`, `${config.backendUrl}/filaments/${filamentId}`,
{ {
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'
@ -129,7 +131,7 @@ const FilamentInfo = () => {
setLoading(true) setLoading(true)
await axios.put( await axios.put(
`http://localhost:8080/filaments/${filamentId}`, `${config.backendUrl}/filaments/${filamentId}`,
{ {
name: values.name, name: values.name,
vendor: values.vendor, vendor: values.vendor,
@ -170,7 +172,7 @@ const FilamentInfo = () => {
const handleDelete = async () => { const handleDelete = async () => {
try { try {
setLoading(true) setLoading(true)
await axios.delete(`http://localhost:8080/filaments/${filamentId}`, { await axios.delete(`${config.backendUrl}/filaments/${filamentId}`, {
withCredentials: true withCredentials: true
}) })
messageApi.success('Filament deleted successfully') messageApi.success('Filament deleted successfully')

View File

@ -20,6 +20,8 @@ import {
import { UploadOutlined, LinkOutlined } from '@ant-design/icons' import { UploadOutlined, LinkOutlined } from '@ant-design/icons'
import VendorSelect from '../../common/VendorSelect' import VendorSelect from '../../common/VendorSelect'
import config from '../../../../config'
const { Title } = Typography const { Title } = Typography
const initialNewFilamentForm = { const initialNewFilamentForm = {
@ -129,7 +131,7 @@ const NewFilament = ({ onOk, reset }) => {
setNewFilamentLoading(true) setNewFilamentLoading(true)
try { try {
await axios.post( await axios.post(
`http://localhost:8080/filaments`, `${config.backendUrl}/filaments`,
newFilamentFormValues, newFilamentFormValues,
{ {
withCredentials: true // Important for including cookies withCredentials: true // Important for including cookies

View File

@ -26,6 +26,8 @@ import PlusIcon from '../../Icons/PlusIcon'
import ReloadIcon from '../../Icons/ReloadIcon' import ReloadIcon from '../../Icons/ReloadIcon'
import TimeDisplay from '../common/TimeDisplay' import TimeDisplay from '../common/TimeDisplay'
import config from '../../../config'
const useStyle = createStyles(({ css, token }) => { const useStyle = createStyles(({ css, token }) => {
const { antCls } = token const { antCls } = token
return { return {
@ -61,7 +63,7 @@ const Materials = () => {
const fetchMaterialsData = useCallback( const fetchMaterialsData = useCallback(
async (pageNum = 1, append = false) => { async (pageNum = 1, append = false) => {
try { try {
const response = await axios.get('http://localhost:8080/materials', { const response = await axios.get(`${config.backendUrl}/materials`, {
params: { params: {
page: pageNum, page: pageNum,
limit: 25 limit: 25

View File

@ -16,6 +16,8 @@ import {
import { UploadOutlined } from '@ant-design/icons' import { UploadOutlined } from '@ant-design/icons'
import VendorSelect from '../../common/VendorSelect' import VendorSelect from '../../common/VendorSelect'
import config from '../../../../config'
const initialNewMaterialForm = { const initialNewMaterialForm = {
name: '', name: '',
vendor: { id: null, name: '' }, vendor: { id: null, name: '' },
@ -93,7 +95,7 @@ const NewMaterial = ({ onSuccess }) => {
setNewMaterialLoading(true) setNewMaterialLoading(true)
try { try {
await axios.post( await axios.post(
`http://localhost:8080/materials`, `${config.backendUrl}/materials`,
newMaterialFormValues, newMaterialFormValues,
{ {
withCredentials: true withCredentials: true

View File

@ -33,6 +33,8 @@ import CheckIcon from '../../Icons/CheckIcon'
import useColumnVisibility from '../hooks/useColumnVisibility' import useColumnVisibility from '../hooks/useColumnVisibility'
import TimeDisplay from '../common/TimeDisplay' import TimeDisplay from '../common/TimeDisplay'
import config from '../../../config'
const { Text } = Typography const { Text } = Typography
const useStyle = createStyles(({ css, token }) => { const useStyle = createStyles(({ css, token }) => {
@ -206,7 +208,7 @@ const Parts = () => {
const fetchPartsData = useCallback( const fetchPartsData = useCallback(
async (pageNum = 1, append = false) => { async (pageNum = 1, append = false) => {
try { try {
const response = await axios.get('http://localhost:8080/parts', { const response = await axios.get(`${config.backendUrl}/parts`, {
params: { params: {
page: pageNum, page: pageNum,
limit: 25, limit: 25,

View File

@ -28,6 +28,8 @@ import CheckIcon from '../../../Icons/CheckIcon.jsx'
import useCollapseState from '../../hooks/useCollapseState' import useCollapseState from '../../hooks/useCollapseState'
import TimeDisplay from '../../common/TimeDisplay.jsx' import TimeDisplay from '../../common/TimeDisplay.jsx'
import config from '../../../../config.js'
const { Title } = Typography const { Title } = Typography
const PartInfo = () => { const PartInfo = () => {
@ -93,15 +95,12 @@ const PartInfo = () => {
const fetchPartDetails = async () => { const fetchPartDetails = async () => {
try { try {
setFetchLoading(true) setFetchLoading(true)
const response = await axios.get( const response = await axios.get(`${config.backendUrl}/parts/${partId}`, {
`http://localhost:8080/parts/${partId}`, headers: {
{ Accept: 'application/json'
headers: { },
Accept: 'application/json' withCredentials: true
}, })
withCredentials: true
}
)
setPartData(response.data) setPartData(response.data)
setError(null) setError(null)
} catch (err) { } catch (err) {
@ -125,7 +124,7 @@ const PartInfo = () => {
objectUrlRef.current = null objectUrlRef.current = null
} }
const response = await axios.get( const response = await axios.get(
`http://localhost:8080/parts/${partId}/content`, `${config.backendUrl}/parts/${partId}/content`,
{ {
withCredentials: true, withCredentials: true,
responseType: 'blob' responseType: 'blob'
@ -190,7 +189,7 @@ const PartInfo = () => {
const values = await partForm.validateFields() const values = await partForm.validateFields()
setLoading(true) setLoading(true)
await axios.put(`http://localhost:8080/parts/${partId}`, values, { await axios.put(`${config.backendUrl}/parts/${partId}`, values, {
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },

View File

@ -34,6 +34,8 @@ import CheckIcon from '../../Icons/CheckIcon'
import useColumnVisibility from '../hooks/useColumnVisibility' import useColumnVisibility from '../hooks/useColumnVisibility'
import config from '../../../config'
const useStyle = createStyles(({ css, token }) => { const useStyle = createStyles(({ css, token }) => {
const { antCls } = token const { antCls } = token
return { return {
@ -73,7 +75,7 @@ const Products = () => {
const fetchProductsData = useCallback( const fetchProductsData = useCallback(
async (pageNum = 1, append = false) => { async (pageNum = 1, append = false) => {
try { try {
const response = await axios.get('http://localhost:8080/products', { const response = await axios.get(`${config.backendUrl}/products`, {
params: { params: {
page: pageNum, page: pageNum,
limit: 25, limit: 25,

View File

@ -23,6 +23,8 @@ import PartIcon from '../../../Icons/PartIcon'
import { StlViewer } from 'react-stl-viewer' import { StlViewer } from 'react-stl-viewer'
import VendorSelect from '../../common/VendorSelect' import VendorSelect from '../../common/VendorSelect'
import config from '../../../../config'
const { Dragger } = Upload const { Dragger } = Upload
const { Title, Text } = Typography const { Title, Text } = Typography
@ -166,7 +168,7 @@ const NewProduct = ({ onOk, reset }) => {
setNewProductLoading(true) setNewProductLoading(true)
try { try {
const result = await axios.post( const result = await axios.post(
`http://localhost:8080/products`, `${config.backendUrl}/products`,
newProductFormValues, newProductFormValues,
{ {
withCredentials: true // Important for including cookies withCredentials: true // Important for including cookies
@ -192,7 +194,7 @@ const NewProduct = ({ onOk, reset }) => {
formData.append('partFile', parts[i].file) formData.append('partFile', parts[i].file)
await axios.post( await axios.post(
`http://localhost:8080/parts/${partIds[i]}/content`, `${config.backendUrl}/parts/${partIds[i]}/content`,
formData, formData,
{ {
headers: { headers: {

View File

@ -28,6 +28,8 @@ import XMarkIcon from '../../../Icons/XMarkIcon.jsx'
import CheckIcon from '../../../Icons/CheckIcon.jsx' import CheckIcon from '../../../Icons/CheckIcon.jsx'
import TimeDisplay from '../../common/TimeDisplay.jsx' import TimeDisplay from '../../common/TimeDisplay.jsx'
import config from '../../../../config.js'
const { Title } = Typography const { Title } = Typography
const ProductInfo = () => { const ProductInfo = () => {
@ -97,7 +99,7 @@ const ProductInfo = () => {
try { try {
setFetchLoading(true) setFetchLoading(true)
const response = await axios.get( const response = await axios.get(
`http://localhost:8080/products/${productId}`, `${config.backendUrl}/products/${productId}`,
{ {
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'
@ -142,7 +144,7 @@ const ProductInfo = () => {
const values = await productForm.validateFields() const values = await productForm.validateFields()
setLoading(true) setLoading(true)
await axios.put(`http://localhost:8080/products/${productId}`, values, { await axios.put(`${config.backendUrl}/products/${productId}`, values, {
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },

View File

@ -30,6 +30,8 @@ import CheckIcon from '../../Icons/CheckIcon'
import useColumnVisibility from '../hooks/useColumnVisibility' import useColumnVisibility from '../hooks/useColumnVisibility'
import InfoCircleIcon from '../../Icons/InfoCircleIcon' import InfoCircleIcon from '../../Icons/InfoCircleIcon'
import config from '../../../config'
const { Link } = Typography const { Link } = Typography
const useStyle = createStyles(({ css, token }) => { const useStyle = createStyles(({ css, token }) => {
@ -68,7 +70,7 @@ const Vendors = () => {
const fetchVendorsData = useCallback( const fetchVendorsData = useCallback(
async (pageNum = 1, append = false) => { async (pageNum = 1, append = false) => {
try { try {
const response = await axios.get('http://localhost:8080/vendors', { const response = await axios.get(`${config.backendUrl}/vendors`, {
params: { params: {
page: pageNum, page: pageNum,
limit: 25, limit: 25,

View File

@ -16,6 +16,8 @@ import {
import CountrySelect from '../../common/CountrySelect' import CountrySelect from '../../common/CountrySelect'
import CountryDisplay from '../../common/CountryDisplay' import CountryDisplay from '../../common/CountryDisplay'
import config from '../../../../config'
const { Title } = Typography const { Title } = Typography
const initialNewVendorForm = { const initialNewVendorForm = {
@ -93,7 +95,7 @@ const NewVendor = ({ onOk, reset }) => {
const handleNewVendor = async () => { const handleNewVendor = async () => {
setNewVendorLoading(true) setNewVendorLoading(true)
try { try {
await axios.post('http://localhost:8080/vendors', newVendorFormValues, { await axios.post(`${config.backendUrl}/vendors`, newVendorFormValues, {
withCredentials: true withCredentials: true
}) })
onOk() onOk()

View File

@ -28,6 +28,8 @@ import XMarkIcon from '../../../Icons/XMarkIcon.jsx'
import CheckIcon from '../../../Icons/CheckIcon.jsx' import CheckIcon from '../../../Icons/CheckIcon.jsx'
import useCollapseState from '../../hooks/useCollapseState' import useCollapseState from '../../hooks/useCollapseState'
import config from '../../../../config.js'
const { Title, Link } = Typography const { Title, Link } = Typography
const VendorInfo = () => { const VendorInfo = () => {
@ -67,7 +69,7 @@ const VendorInfo = () => {
try { try {
setFetchLoading(true) setFetchLoading(true)
const response = await axios.get( const response = await axios.get(
`http://localhost:8080/vendors/${vendorId}`, `${config.backendUrl}/vendors/${vendorId}`,
{ {
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'
@ -107,7 +109,7 @@ const VendorInfo = () => {
const values = await form.validateFields() const values = await form.validateFields()
setLoading(true) setLoading(true)
await axios.put(`http://localhost:8080/vendors/${vendorId}`, values, { await axios.put(`${config.backendUrl}/vendors/${vendorId}`, values, {
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },

View File

@ -34,6 +34,8 @@ import XMarkIcon from '../../Icons/XMarkIcon'
import CheckIcon from '../../Icons/CheckIcon' import CheckIcon from '../../Icons/CheckIcon'
import TimeDisplay from '../common/TimeDisplay' import TimeDisplay from '../common/TimeDisplay'
import config from '../../../config'
const { Text } = Typography const { Text } = Typography
const useStyle = createStyles(({ css, token }) => { const useStyle = createStyles(({ css, token }) => {
@ -259,7 +261,7 @@ const GCodeFiles = () => {
order: sorter.order order: sorter.order
} }
const response = await axios.get('http://localhost:8080/gcodefiles', { const response = await axios.get(`${config.backendUrl}/gcodefiles`, {
params, params,
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'
@ -369,7 +371,7 @@ const GCodeFiles = () => {
} }
try { try {
const response = await axios.get( const response = await axios.get(
`http://localhost:8080/gcodefiles/${id}/content`, `${config.backendUrl}/gcodefiles/${id}/content`,
{ {
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'

View File

@ -27,6 +27,8 @@ import EditIcon from '../../../Icons/EditIcon.jsx'
import XMarkIcon from '../../../Icons/XMarkIcon.jsx' import XMarkIcon from '../../../Icons/XMarkIcon.jsx'
import CheckIcon from '../../../Icons/CheckIcon.jsx' import CheckIcon from '../../../Icons/CheckIcon.jsx'
import config from '../../../../config.js'
const { Title } = Typography const { Title } = Typography
const GCodeFileInfo = () => { const GCodeFileInfo = () => {
@ -66,7 +68,7 @@ const GCodeFileInfo = () => {
try { try {
setFetchLoading(true) setFetchLoading(true)
const response = await axios.get( const response = await axios.get(
`http://localhost:8080/gcodefiles/${gcodeFileId}`, `${config.backendUrl}/gcodefiles/${gcodeFileId}`,
{ {
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'
@ -103,7 +105,7 @@ const GCodeFileInfo = () => {
setLoading(true) setLoading(true)
await axios.put( await axios.put(
`http://localhost:8080/gcodefiles/${gcodeFileId}`, `${config.backendUrl}/gcodefiles/${gcodeFileId}`,
values, values,
{ {
headers: { headers: {

View File

@ -29,6 +29,8 @@ import GCodeFileIcon from '../../../Icons/GCodeFileIcon'
import FilamentSelect from '../../common/FilamentSelect' import FilamentSelect from '../../common/FilamentSelect'
import config from '../../../../config.js'
const { Dragger } = Upload const { Dragger } = Upload
const { Title } = Typography const { Title } = Typography
@ -79,7 +81,7 @@ const NewGCodeFile = ({ onOk, reset }) => {
try { try {
setNextLoading(true) setNextLoading(true)
const response = await axios.get( const response = await axios.get(
`http://localhost:8080/filaments/${newGCodeFileFormValues.filament}`, `${config.backendUrl}/filaments/${newGCodeFileFormValues.filament}`,
{ {
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'
@ -230,7 +232,7 @@ const NewGCodeFile = ({ onOk, reset }) => {
formData.append('gcodeFile', gcodeFile) formData.append('gcodeFile', gcodeFile)
try { try {
await axios.post( await axios.post(
`http://localhost:8080/gcodefiles/${id}/content`, `${config.backendUrl}/gcodefiles/${id}/content`,
formData, formData,
{ {
headers: { headers: {
@ -253,7 +255,7 @@ const NewGCodeFile = ({ onOk, reset }) => {
setNewGCodeFileLoading(true) setNewGCodeFileLoading(true)
try { try {
const request = await axios.post( const request = await axios.post(
`http://localhost:8080/gcodefiles`, `${config.backendUrl}/gcodefiles`,
newGCodeFileFormValues, newGCodeFileFormValues,
{ {
headers: { headers: {
@ -279,7 +281,7 @@ const NewGCodeFile = ({ onOk, reset }) => {
// Call the API to extract and parse the config block // Call the API to extract and parse the config block
const request = await axios.post( const request = await axios.post(
`http://localhost:8080/gcodefiles/content`, `${config.backendUrl}/gcodefiles/content`,
formData, formData,
{ {
withCredentials: true // Important for including cookies withCredentials: true // Important for including cookies

View File

@ -44,6 +44,8 @@ import EditIcon from '../../Icons/EditIcon.jsx'
import XMarkIcon from '../../Icons/XMarkIcon.jsx' import XMarkIcon from '../../Icons/XMarkIcon.jsx'
import CheckIcon from '../../Icons/CheckIcon.jsx' import CheckIcon from '../../Icons/CheckIcon.jsx'
import config from '../../../config.js'
const { Text } = Typography const { Text } = Typography
const useStyle = createStyles(({ css, token }) => { const useStyle = createStyles(({ css, token }) => {
@ -331,7 +333,7 @@ const PrintJobs = () => {
order: sorter.order order: sorter.order
} }
const response = await axios.get('http://localhost:8080/printjobs', { const response = await axios.get(`${config.backendUrl}/printjobs`, {
params, params,
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'

View File

@ -16,6 +16,8 @@ import PropTypes from 'prop-types'
import GCodeFileSelect from '../../common/GCodeFileSelect' import GCodeFileSelect from '../../common/GCodeFileSelect'
import PrinterSelect from '../../common/PrinterSelect' import PrinterSelect from '../../common/PrinterSelect'
import config from '../../../../config'
const { Title } = Typography const { Title } = Typography
const initialNewPrintJobForm = { const initialNewPrintJobForm = {
@ -67,7 +69,7 @@ const NewPrintJob = ({ onOk, reset }) => {
setNewPrintJobLoading(true) setNewPrintJobLoading(true)
try { try {
await axios.post( await axios.post(
`http://localhost:8080/printjobs`, `${config.backendUrl}/printjobs`,
newPrintJobFormValues, newPrintJobFormValues,
{ {
headers: { headers: {

View File

@ -20,6 +20,7 @@ import { SocketContext } from '../../context/SocketContext'
import GCodeFileIcon from '../../../Icons/GCodeFileIcon' import GCodeFileIcon from '../../../Icons/GCodeFileIcon'
import ReloadIcon from '../../../Icons/ReloadIcon' import ReloadIcon from '../../../Icons/ReloadIcon'
import useCollapseState from '../../hooks/useCollapseState' import useCollapseState from '../../hooks/useCollapseState'
import config from '../../../../config'
const { Title } = Typography const { Title } = Typography
@ -72,7 +73,7 @@ const PrintJobInfo = () => {
try { try {
setLoading(true) setLoading(true)
const response = await axios.get( const response = await axios.get(
`http://localhost:8080/printjobs/${printJobId}`, `${config.backendUrl}/printjobs/${printJobId}`,
{ {
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'

View File

@ -32,6 +32,8 @@ import ReloadIcon from '../../Icons/ReloadIcon'
import XMarkIcon from '../../Icons/XMarkIcon' import XMarkIcon from '../../Icons/XMarkIcon'
import CheckIcon from '../../Icons/CheckIcon' import CheckIcon from '../../Icons/CheckIcon'
import config from '../../../config'
const useStyle = createStyles(({ css, token }) => { const useStyle = createStyles(({ css, token }) => {
const { antCls } = token const { antCls } = token
return { return {
@ -236,7 +238,7 @@ const Printers = () => {
order: sorter.order order: sorter.order
} }
const response = await axios.get('http://localhost:8080/printers', { const response = await axios.get(`${config.backendUrl}/printers`, {
params, params,
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'

View File

@ -45,6 +45,8 @@ import LoadFilamentStock from '../../Inventory/FilamentStocks/LoadFilamentStock'
import UnloadFilamentStock from '../../Inventory/FilamentStocks/UnloadFilamentStock' import UnloadFilamentStock from '../../Inventory/FilamentStocks/UnloadFilamentStock'
import FilamentStockState from '../../common/FilamentStockState' import FilamentStockState from '../../common/FilamentStockState'
import config from '../../../../config'
const { Text } = Typography const { Text } = Typography
// Helper function to parse query parameters // Helper function to parse query parameters
@ -96,7 +98,7 @@ const ControlPrinter = () => {
if (printerId) { if (printerId) {
try { try {
const response = await axios.get( const response = await axios.get(
`http://localhost:8080/printers/${printerId}`, `${config.backendUrl}/printers/${printerId}`,
{ {
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'
@ -610,25 +612,6 @@ const ControlPrinter = () => {
</Descriptions.Item> </Descriptions.Item>
)} )}
<Descriptions.Item label='Est. Print Time'>
{(() => {
if (
printerData.currentJob?.gcodeFile?.gcodeFileInfo
.estimatedPrintingTimeNormalMode
) {
return (
<Text ellipsis>
{
printerData.currentJob.gcodeFile.gcodeFileInfo
.estimatedPrintingTimeNormalMode
}
</Text>
)
}
return 'n/a'
})()}
</Descriptions.Item>
<Descriptions.Item label='Print Profile'> <Descriptions.Item label='Print Profile'>
{(() => { {(() => {
if ( if (
@ -648,6 +631,25 @@ const ControlPrinter = () => {
} }
})()} })()}
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item label='Est. Print Time'>
{(() => {
if (
printerData.currentJob?.gcodeFile?.gcodeFileInfo
.estimatedPrintingTimeNormalMode
) {
return (
<Text ellipsis>
{
printerData.currentJob.gcodeFile.gcodeFileInfo
.estimatedPrintingTimeNormalMode
}
</Text>
)
}
return 'n/a'
})()}
</Descriptions.Item>
</Descriptions> </Descriptions>
{componentVisibility.subjobs && ( {componentVisibility.subjobs && (
<PrinterSubJobsTree subJobs={printerData.subJobs} /> <PrinterSubJobsTree subJobs={printerData.subJobs} />

View File

@ -24,6 +24,8 @@ import PropTypes from 'prop-types'
import { SocketContext } from '../../context/SocketContext' import { SocketContext } from '../../context/SocketContext'
import EditIcon from '../../../Icons/EditIcon.jsx' import EditIcon from '../../../Icons/EditIcon.jsx'
import config from '../../../../config.js'
const { Title } = Typography const { Title } = Typography
const initialNewPrinterForm = { const initialNewPrinterForm = {
@ -154,7 +156,7 @@ const NewPrinter = ({ onOk, reset }) => {
setNewPrinterLoading(true) setNewPrinterLoading(true)
try { try {
await axios.post( await axios.post(
'http://localhost:8080/printers', `${config.backendUrl}/printers`,
{ {
...newPrinterFormValues ...newPrinterFormValues
}, },

View File

@ -30,6 +30,8 @@ import XMarkIcon from '../../../Icons/XMarkIcon.jsx'
import CheckIcon from '../../../Icons/CheckIcon.jsx' import CheckIcon from '../../../Icons/CheckIcon.jsx'
import useCollapseState from '../../hooks/useCollapseState' import useCollapseState from '../../hooks/useCollapseState'
import config from '../../../../config.js'
const { Title } = Typography const { Title } = Typography
const PrinterInfo = () => { const PrinterInfo = () => {
@ -73,7 +75,7 @@ const PrinterInfo = () => {
try { try {
setFetchLoading(true) setFetchLoading(true)
const response = await axios.get( const response = await axios.get(
`http://localhost:8080/printers/${printerId}`, `${config.backendUrl}/printers/${printerId}`,
{ {
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'
@ -120,7 +122,7 @@ const PrinterInfo = () => {
setLoading(true) setLoading(true)
await axios.put( await axios.put(
`http://localhost:8080/printers/${printerId}`, `${config.backendUrl}/printers/${printerId}`,
{ {
name: values.name, name: values.name,
vendor: values.vendor, vendor: values.vendor,

View File

@ -21,6 +21,8 @@ import XMarkIcon from '../../Icons/XMarkIcon'
import useCollapseState from '../hooks/useCollapseState' import useCollapseState from '../hooks/useCollapseState'
import CheckIcon from '../../Icons/CheckIcon' import CheckIcon from '../../Icons/CheckIcon'
import config from '../../../config'
const { Title, Text } = Typography const { Title, Text } = Typography
const ProductionOverview = () => { const ProductionOverview = () => {
@ -64,7 +66,7 @@ const ProductionOverview = () => {
const fetchPrinterStats = async () => { const fetchPrinterStats = async () => {
try { try {
setFetchPrinterStatsLoading(true) setFetchPrinterStatsLoading(true)
const response = await axios.get(`http://localhost:8080/printers/stats`, { const response = await axios.get(`${config.backendUrl}/printers/stats`, {
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'
}, },
@ -85,15 +87,12 @@ const ProductionOverview = () => {
const fetchPrintJobStats = async () => { const fetchPrintJobStats = async () => {
try { try {
setFetchPrinterStatsLoading(true) setFetchPrinterStatsLoading(true)
const response = await axios.get( const response = await axios.get(`${config.backendUrl}/printjobs/stats`, {
`http://localhost:8080/printjobs/stats`, headers: {
{ Accept: 'application/json'
headers: { },
Accept: 'application/json' withCredentials: true
}, })
withCredentials: true
}
)
const printJobStats = response.data const printJobStats = response.data
setStats((prev) => ({ ...prev, printJobs: printJobStats })) setStats((prev) => ({ ...prev, printJobs: printJobStats }))
setError(null) setError(null)

View File

@ -4,6 +4,8 @@ import React, { useEffect, useState, useCallback } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import axios from 'axios' import axios from 'axios'
import config from '../../../config'
const propertyOrder = ['diameter', 'type', 'vendor.name'] const propertyOrder = ['diameter', 'type', 'vendor.name']
const FilamentSelect = ({ onChange, filter, useFilter, value }) => { const FilamentSelect = ({ onChange, filter, useFilter, value }) => {
@ -15,7 +17,7 @@ const FilamentSelect = ({ onChange, filter, useFilter, value }) => {
const fetchFilamentsData = async (property, filter) => { const fetchFilamentsData = async (property, filter) => {
setLoading(true) setLoading(true)
try { try {
const response = await axios.get('http://localhost:8080/filaments', { const response = await axios.get(`${config.backendUrl}/filaments`, {
params: { params: {
...filter, ...filter,
property property

View File

@ -2,6 +2,7 @@ import { TreeSelect } from 'antd'
import React, { useEffect, useState, useCallback } from 'react' import React, { useEffect, useState, useCallback } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import axios from 'axios' import axios from 'axios'
import config from '../../../config'
import FilamentStockDisplay from './FilamentStockDisplay' import FilamentStockDisplay from './FilamentStockDisplay'
@ -20,7 +21,7 @@ const FilamentStockSelect = ({ onChange, filter, useFilter, value }) => {
const fetchFilamentStocksData = async (property, filter) => { const fetchFilamentStocksData = async (property, filter) => {
setLoading(true) setLoading(true)
try { try {
const response = await axios.get('http://localhost:8080/filamentstocks', { const response = await axios.get(`${config.backendUrl}/filamentstocks`, {
params: { params: {
...filter, ...filter,
property property

View File

@ -6,6 +6,8 @@ import axios from 'axios'
import GCodeFileIcon from '../../Icons/GCodeFileIcon' import GCodeFileIcon from '../../Icons/GCodeFileIcon'
import { AuthContext } from '../../Auth/AuthContext' import { AuthContext } from '../../Auth/AuthContext'
import config from '../../../config'
const propertyOrder = [ const propertyOrder = [
'filament.diameter', 'filament.diameter',
'filament.type', 'filament.type',
@ -28,7 +30,7 @@ const GCodeFileSelect = ({ onChange, filter, useFilter }) => {
} }
setLoading(true) setLoading(true)
try { try {
const response = await axios.get('http://localhost:8080/gcodefiles', { const response = await axios.get(`${config.backendUrl}/gcodefiles`, {
params: { params: {
...filter, ...filter,
search, search,

View File

@ -16,7 +16,7 @@ const PartSelect = ({ onChange, filter, useFilter }) => {
const fetchPartsData = async (property, filter) => { const fetchPartsData = async (property, filter) => {
setLoading(true) setLoading(true)
try { try {
const response = await axios.get('http://localhost:8080/parts', { const response = await axios.get(`${config.backendUrl}/parts', {
params: { params: {
...filter, ...filter,
property property

View File

@ -21,7 +21,7 @@ const PartTransfer = ({
const fetchPartsData = async (property, filter) => { const fetchPartsData = async (property, filter) => {
setLoading(true) setLoading(true)
try { try {
const response = await axios.get('http://localhost:8080/parts', { const response = await axios.get(`${config.backendUrl}/parts', {
params: { params: {
...filter, ...filter,
property property

View File

@ -11,6 +11,8 @@ import JobIcon from '../../Icons/JobIcon'
import SubJobIcon from '../../Icons/SubJobIcon' import SubJobIcon from '../../Icons/SubJobIcon'
import ReloadIcon from '../../Icons/ReloadIcon' import ReloadIcon from '../../Icons/ReloadIcon'
import config from '../../../config'
const PrinterJobsTree = ({ subJobs: initialSubJobs }) => { const PrinterJobsTree = ({ subJobs: initialSubJobs }) => {
const [subJobs, setSubJobs] = useState(initialSubJobs || []) const [subJobs, setSubJobs] = useState(initialSubJobs || [])
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
@ -93,7 +95,7 @@ const PrinterJobsTree = ({ subJobs: initialSubJobs }) => {
if (!initialSubJobs) { if (!initialSubJobs) {
try { try {
setLoading(true) setLoading(true)
const response = await axios.get('http://localhost:8080/printjobs', { const response = await axios.get(`${config.backendUrl}/printjobs`, {
headers: { Accept: 'application/json' }, headers: { Accept: 'application/json' },
withCredentials: true withCredentials: true
}) })

View File

@ -5,6 +5,7 @@ import React, { useEffect, useState, useContext } from 'react'
import axios from 'axios' import axios from 'axios'
import PrinterState from './PrinterState' import PrinterState from './PrinterState'
import { AuthContext } from '../../Auth/AuthContext' import { AuthContext } from '../../Auth/AuthContext'
import config from '../../../config'
const PrinterSelect = ({ onChange, disabled, checkable, value = [] }) => { const PrinterSelect = ({ onChange, disabled, checkable, value = [] }) => {
const [printersTreeData, setPrintersTreeData] = useState([]) const [printersTreeData, setPrintersTreeData] = useState([])
@ -22,7 +23,7 @@ const PrinterSelect = ({ onChange, disabled, checkable, value = [] }) => {
setLoading(true) setLoading(true)
try { try {
const response = await axios.get('http://localhost:8080/printers', { const response = await axios.get(`${config.backendUrl}/printers`, {
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'
}, },

View File

@ -12,6 +12,8 @@ import SubJobState from './SubJobState'
import SubJobIcon from '../../Icons/SubJobIcon' import SubJobIcon from '../../Icons/SubJobIcon'
import ReloadIcon from '../../Icons/ReloadIcon' import ReloadIcon from '../../Icons/ReloadIcon'
import config from '../../../config'
const SubJobsTree = ({ printJobData }) => { const SubJobsTree = ({ printJobData }) => {
const [treeData, setTreeData] = useState([]) const [treeData, setTreeData] = useState([])
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
@ -89,7 +91,7 @@ const SubJobsTree = ({ printJobData }) => {
if (!printJobData) { if (!printJobData) {
try { try {
setLoading(true) setLoading(true)
const response = await axios.get('http://localhost:8080/printjobs', { const response = await axios.get(`${config.backendUrl}/printjobs`, {
headers: { Accept: 'application/json' }, headers: { Accept: 'application/json' },
withCredentials: true withCredentials: true
}) })

View File

@ -4,6 +4,7 @@ import PropTypes from 'prop-types'
import axios from 'axios' import axios from 'axios'
import CountryDisplay from './CountryDisplay' import CountryDisplay from './CountryDisplay'
import VendorIcon from '../../Icons/VendorIcon' import VendorIcon from '../../Icons/VendorIcon'
import config from '../../../config'
const propertyOrder = ['country'] const propertyOrder = ['country']
@ -15,7 +16,7 @@ const VendorSelect = ({ onChange, filter = {}, useFilter = false, value }) => {
const fetchVendorsData = async (property, filter) => { const fetchVendorsData = async (property, filter) => {
setLoading(true) setLoading(true)
try { try {
const response = await axios.get('http://localhost:8080/vendors', { const response = await axios.get(`${config.backendUrl}/vendors`, {
params: { params: {
...filter, ...filter,
property property

View File

@ -10,6 +10,7 @@ import io from 'socket.io-client'
import { message, notification } from 'antd' import { message, notification } from 'antd'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { AuthContext } from '../../Auth/AuthContext' import { AuthContext } from '../../Auth/AuthContext'
import config from '../../../config'
const SocketContext = createContext() const SocketContext = createContext()
@ -25,7 +26,7 @@ const SocketProvider = ({ children }) => {
if (token) { if (token) {
console.log('Token is available, connecting to web socket server...') console.log('Token is available, connecting to web socket server...')
const newSocket = io('http://localhost:8081', { const newSocket = io(config.wsUrl, {
reconnectionAttempts: 3, reconnectionAttempts: 3,
timeout: 3000, timeout: 3000,
auth: { token: token } auth: { token: token }

View File

@ -11,6 +11,8 @@ import PrinterState from '../common/PrinterState'
import JobState from '../common/JobState' import JobState from '../common/JobState'
import IdText from '../common/IdText' import IdText from '../common/IdText'
import config from '../../../config'
const SpotlightContext = createContext() const SpotlightContext = createContext()
const SpotlightProvider = ({ children }) => { const SpotlightProvider = ({ children }) => {
@ -56,7 +58,7 @@ const SpotlightProvider = ({ children }) => {
setLoading(true) setLoading(true)
setListData([]) setListData([])
const response = await axios.get( const response = await axios.get(
`http://localhost:8080/spotlight/${encodeURIComponent(searchQuery.trim())}`, `${config.backendUrl}/spotlight/${encodeURIComponent(searchQuery.trim())}`,
{ {
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'

16
src/config.js Normal file
View File

@ -0,0 +1,16 @@
const config = {
development: {
backendUrl: 'http://localhost:8080',
wsUrl: 'ws://localhost:8081'
},
production: {
backendUrl: 'https://api.farmcontrol.com', // Replace with your production backend URL
wsUrl: 'wss://api.farmcontrol.com' // Replace with your production WebSocket URL
}
}
// Get the current environment, defaulting to development
const env = process.env.NODE_ENV || 'development'
// Export the configuration for the current environment
export default config[env]