videos and images sent are not being saved in my Electron + React.js build

When I use npm start and run the app normally, I can add and view all images and videos without any issues. However, when I build the app, everything else gets saved correctly, but the images fail to load. Apart from loading images or videos, everything else works fine. When I check the database in local files, the image field appears empty. By the way, I’m using a local database (db-local).

Additionally, if you notice any potential issues beyond what I’ve mentioned, I’d appreciate it if you could point them out. I’m primarily a back-end developer, and this is my first front-end and Electron project.

react.js part

import React from 'react'
import Typography from '@mui/material/Typography';
import Select from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem';
import Paper from '@mui/material/Paper';
import Chip from '@mui/material/Chip';
import Button from '@mui/material/Button';
import Box from '@mui/material/Box';
import TextField from '@mui/material/TextField';
import InputAdornment from '@mui/material/InputAdornment';
import { useDispatch } from 'react-redux';
import { startloading } from '../store/slices/userSlice';
import { Controller, useForm } from 'react-hook-form';
import AddIcon from '@mui/icons-material/AddRounded';
import IconButton from '@mui/material/IconButton';
import Attachment from '@mui/icons-material/AttachmentRounded';
import MediaPreview from '../components/MediaPreview';
import { Container, Switch } from '@mui/material';
import { useNavigate } from 'react-router-dom';
import ArrowBackIos from '@mui/icons-material/ArrowBackIosRounded';
const AddRule = () => {
    const [type, setType] = React.useState('');
    const [newRule, setNewRule] = React.useState('');
    const [controlledRules, setControlledRules] = React.useState([]);
    const [preview, setPreview] = React.useState(null);
    const [previewOpen, setPreviewOpen] = React.useState(true);
    const [error, setError] = React.useState(null);
    const ruleInputRef = React.useRef(null);
    const dispatch = useDispatch();

    const {
        control,
        handleSubmit,
        getValues,
        reset,
        setValue,
        formState: { errors },
    } = useForm({
        values: React.useMemo(() => ({
            rules: [],
            rule_title: "",
            rule_timeout_unit: "seconds",
            rule_timeout: 1,
            rule_delay: 1,
            rule_response: "",
            image: ""
        }), [])
    })

    const addRuleHandler = (rule) => {
        if (rule.trim() === '') return setError(prevError => ({ ...prevError, rules: "Kural boş bırakılamaz." }));
        if (controlledRules.includes(rule)) return setError(prevError => ({ ...prevError, rules: "Her kural bir kere girilmelidir." }))
        setControlledRules([...controlledRules, rule])
        setError(prevError => ({ ...prevError, rules: "" }))
        setNewRule('');
    }

    React.useEffect(() => {
        setValue("rules", controlledRules);
    }, [controlledRules, setValue]);

    const deleteRuleHandler = (rule) => {
        setControlledRules(controlledRules.filter(r => r !== rule))
    }

    const handleFileChange = (file, field) => {
        if (file && (file.type === "video/mp4" || file.type === "image/png" || file.type === "image/jpeg")) {
            const maxSize = 15 * 1024 * 1024;
            if (file.size > maxSize) {
                return setError(prevError => ({ ...prevError, file: "Medya boyutu 15MB'dan büyük olamaz." }));
            }

            const reader = new FileReader();

            reader.onloadend = () => {
                const base64 = reader.result.split(",")[1];
                field.onChange(base64);
                setValue("image", base64)
            };

            reader.readAsDataURL(file);
            setType(file.type);
            setPreview({ url: URL.createObjectURL(file), type: file.type });
            setError(null);
        } else {
            setError(prevError => ({ ...prevError, file: "Sadece .png, .jpg veya .mp4 dosyaları yüklenebilir." }));
            field.onChange("");
            setPreview(null);
        }
    };

    const onSubmit = data => {
        if (controlledRules.length == 0) return setError(prevError => ({ ...prevError, rules: "Kural boş bırakılamaz." }))
        dispatch({
            type: 'websocket/sendMessage', payload: {
                data_type: 'add_rule', formdata: { ...data, type }
            }
        });
        dispatch(startloading());
        dispatch({ type: 'websocket/sendMessage', payload: { data_type: 'get_rules' } });
        setControlledRules([]);
        setPreview(null);
        fileInputRef.current.value = "";
        reset()
    };

    const fileInputRef = React.useRef(null);

    const handleFileDelete = () => {
        setError(null);
        setPreview(null);
        setValue("image", "");
        if (fileInputRef.current) {
            fileInputRef.current.value = "";
        }
        setType("");
    }

    const navigate = useNavigate();

    return (
        <Container>
            <form onSubmit={handleSubmit(onSubmit)}>
                <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                    <IconButton onClick={() => navigate('/')}>
                        <ArrowBackIos />
                    </IconButton>
                    <Typography sx={{ fontWeight: '400', margin: '40px 0', fontSize: '32px', textAlign: 'center' }} variant='h5'>Kural Ekleyin</Typography>
                    <Box />
                </Box>
                <Controller name="rule_title"
                    control={control}
                    rules={{
                        required: "Kural başlığı gereklidir",
                        minLength: { value: 3, message: "Başlık en az 3 karakter olmalı" },
                        maxLength: { value: 25, message: "Başlık en fazla 25 karakter olabilir" },
                    }}
                    render={({ field, fieldState }) => (
                        <TextField
                            {...field}
                            sx={{ width: "100%" }}
                            type="text"
                            label="Kural başlığı"
                            placeholder="Kural başlığı girin."
                            variant="outlined"
                            error={!!fieldState.error}
                            helperText={!!fieldState.error ? fieldState.error?.message : ''}
                        />
                    )}
                />
                <Paper sx={{ padding: "10px", marginTop: '10px' }}>
                    <Typography sx={{ fontSize: '16px', fontWeight: '400', display: 'block', textAlign: 'center' }} variant='h6'>Cevap Verme Kuralları</Typography>
                    <Box sx={{ display: 'flex', gap: '5px', flexWrap: 'wrap', padding: "10px", marginTop: '5px' }}>
                        {controlledRules.map((subRule, subIndex) =>
                            <Chip onDelete={() => deleteRuleHandler(subRule)} size='small' key={subIndex} label={subRule} />
                        )}
                    </Box>
                    <TextField
                        size='small'
                        value={newRule}
                        sx={{ width: "100%", marginTop: '15px' }}
                        label="Yeni Kural"
                        onKeyDown={e => {
                            if (e.key === 'Enter') {
                                e.preventDefault();
                                addRuleHandler(newRule);
                            }
                        }}
                        placeholder='Kural girin.'
                        ref={ruleInputRef}
                        onChange={e => setNewRule(e.target.value)}
                        slotProps={{
                            input: {
                                endAdornment: (
                                    <InputAdornment position="end">
                                        <IconButton type='button' onClick={() => addRuleHandler(newRule)}>
                                            <AddIcon />
                                        </IconButton>
                                    </InputAdornment>
                                )
                            }
                        }}
                        error={!!error?.rules}
                        helperText={!!error?.rules ? error.rules : ''}
                    />
                </Paper>

                <Box sx={{ display: 'flex', alignItems: 'flex-start', gap: '5px' }}>
                    <Controller name="rule_timeout"
                        control={control}
                        rules={{
                            min: { value: 1, message: "1 veya daha yüksek bir sayı seçiniz." },
                            max: {
                                value: getValues().rule_timeout_unit === "seconds" || getValues().rule_timeout_unit === "minutes" ? 59
                                    : getValues().rule_timeout_unit === "hours"
                                        ? 23
                                        : 1, message: "Saniye veya Dakika seçili ise en fazla 59, saat seçili ise en fazla 23, güne seçili ise en fazla 1 olmalıdır."
                            },
                        }}
                        render={({ field, fieldState }) => (
                            <TextField
                                {...field}
                                sx={{ width: '100%', marginTop: '20px', }}
                                type="number"
                                label='Tekrar kullanım aralığı'
                                placeholder='Tekrar kullanım aralığını girin.'
                                variant="outlined"
                                error={!!fieldState.error}
                                helperText={!!fieldState.error ? fieldState.error?.message : ''}
                            />
                        )}
                    />
                    <Controller name="rule_timeout_unit"
                        control={control}
                        render={({ field }) => (
                            <Select defaultValue={"seconds"} sx={{ flex: "1", marginTop: '20px' }} {...field} fullWidth>
                                <MenuItem value="seconds">Saniye</MenuItem>
                                <MenuItem value="minutes">Dakika</MenuItem>
                                <MenuItem value="hours">Saat</MenuItem>
                                <MenuItem value="day">Gün</MenuItem>
                                <MenuItem value="onetime">Tek Seferlik</MenuItem>
                            </Select>
                        )}
                    />
                </Box>
                <Controller name="rule_delay"
                    control={control}
                    rules={{
                        min: { value: 1, message: "Cevap gecikmesi en az 1 saniye olabilir." },
                        max: { value: 59, message: "Cevap gecikmesi en fazla 59 saniye olabilir." }
                    }}
                    render={({ field, fieldState }) => (
                        <TextField
                            {...field}
                            sx={{ width: '100%', marginTop: '20px', }}
                            type="number"
                            label='Cevap gecikmesi (Saniye)'
                            placeholder='Cevap gecikmesini girin. (Saniye)'
                            variant="outlined"
                            error={!!fieldState.error}
                            helperText={!!fieldState.error ? fieldState.error?.message : ''}
                        />
                    )}
                />
                <Box sx={{ display: 'flex', alignItems: 'center' }}>
                    <Controller name="image"
                        control={control}
                        render={({ field }) => (
                            <Box sx={{ marginTop: '10px' }}>
                                <>
                                    <label htmlFor="file-upload1">
                                        <Button disabled={getValues().image ? true : false} startIcon={<Attachment />} variant="text" component="span">
                                            Bot cevabına bir medya ekleyin.
                                        </Button>
                                    </label>
                                    <input
                                        disabled={getValues().image ? true : false}
                                        id="file-upload1"
                                        accept=".mp4,.jpg,.png"
                                        multiple={false}
                                        type="file"
                                        ref={fileInputRef}
                                        hidden
                                        onChange={(e) => {
                                            const file = e.target.files[0];
                                            handleFileChange(file, field);
                                        }}
                                    />
                                </>
                            </Box>
                        )}
                    />
                    {preview &&
                        <div style={{ marginTop: '5px' }}>
                            <Switch checked={previewOpen} size='small' onChange={() => setPreviewOpen(!!!previewOpen)} />
                            <Typography variant='body2' component={'span'}>Medyayı Önizle</Typography>
                        </div>
                    }
                </Box>
                {error?.file && <Typography color='error' variant='caption'>{error.file}</Typography>}
                {(preview && previewOpen) &&
                    <MediaPreview setRemove={handleFileDelete} media={preview} />
                }

                <Controller
                    name="rule_response"
                    control={control}
                    rules={{
                        required: { value: true, message: "Bot cevabı gereklidir." },
                        minLength: { value: 3, message: "Bot cevabı en az 3 karakter olabilir." },
                        maxLength: { value: 64000, message: "Bot cevabı en fazla 64.000 karakter olabilir." }
                    }}
                    render={({ field, fieldState }) => (
                        <TextField
                            multiline
                            rows={10}
                            {...field}
                            sx={{ width: '100%', marginTop: '20px', }}
                            type="number"
                            label='Bot cevabı'
                            placeholder='Bot cevabını girin.'
                            variant="outlined"
                            error={!!fieldState.error}
                            helperText={!!fieldState.error ? fieldState.error?.message : ''}
                        />
                    )}
                />
                <Button sx={{ marginTop: '20px' }} size='large' variant='contained' color='success' type='submit'>Kaydet</Button>
                <Button onClick={() => { reset(); setPreview(null); setControlledRules([]); }} sx={{ marginTop: '20px', marginLeft: '5px' }} size='large' color='warning' variant='contained'>Sıfırla</Button>
            </form>
        </Container>
    )
}

export default AddRule

This is electron.js ws part

case "add_rule": {
                object.formdata.rule_delay = parseInt(object.formdata.rule_delay)
                object.formdata.rule_timeout = parseInt(object.formdata.rule_timeout)

                const item = await command.create({ ...object.formdata, image: '' }).save();

                if (object.formdata.image) {
                    const buffer = Buffer.from(object.formdata.image, 'base64');
                    const filePath = path.join(__dirname, 'images', `${item._id + '_' + Date.now()}.${object.formdata.type.split('/')[1]}`);
                    await fs.promises.writeFile(filePath, buffer);
                    const outputFile = 'images/temp_output.mp4';

                    if (object.formdata.type.startsWith('video/')) {
                        ffmpeg(filePath)
                            .videoCodec('libx264')
                            .audioCodec('aac')
                            .audioBitrate(128)
                            .outputOptions('-crf', '23')
                            .outputOptions('-preset', 'fast')
                            .on('start', (commandLine) => {
                                console.log('FFmpeg komutu başladı:', commandLine);
                            })
                            .on('progress', (progress) => {
                                console.log(`İlerleme: ${progress.percent.toFixed(2)}% tamamlandı.`);
                            })
                            .on('end', () => {
                                console.log('FFmpeg işlemi tamamlandı, dosya değiştiriliyor...');
                                fs.unlink(filePath, (err) => {
                                    if (err) {
                                        console.error('Eski dosya silinirken hata oluştu:', err.message);
                                    } else {
                                        fs.rename(outputFile, filePath, (err) => {
                                            if (err) {
                                                console.error('Yeni dosya taşınırken hata oluştu:', err.message);
                                            } else {
                                                console.log('Dosya başarıyla güncellendi!');
                                            }
                                        });
                                    }
                                });
                            })
                            .on('error', (err) => {
                                console.error('Hata oluştu:', err.message);
                                if (fs.existsSync(outputFile)) {
                                    fs.unlink(outputFile, () => {
                                        console.log('Geçici dosya silindi.');
                                    });
                                }
                            })
                            .save(outputFile);
                    }
                    object.formdata.image = filePath;
                    let komut = await command.findOne({ _id: item._id });
                    komut.image = filePath;
                    komut.save();
                }
                wss.clients.forEach((wsClient) =>
                    wsClient.send(JSON.stringify({ data_type: 'rule_added', message: 'Kural başarıyla eklendi.', status: true }))
                )
                break;
            }