convert this react code to svelte

App.css

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700;900&family=Roboto:wght@400;500;700;900&family=Pacifico&display=swap');
:root {
  --background-1: #f1ede9;
}

body {
    font-family: 'Roboto', sans-serif;
    font-size: 1.5vh;
}

#container {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

#prescript-container {
  background-color: var(--background-1);
  height: 49vh;
  width: 46vh;
}

.notepad-top {
  background-color: #333;
  border-top-left-radius: 1vh;
  border-top-right-radius: 1vh;
  height: 5vh;
}

#header {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;

  position: relative;
  border-bottom: 1px solid black;
  padding: 1vh 2vh 1.5vh;
}

.prescription-icon {
  font-size: 2vh;
}

.header-text {
  margin-left: 1vh;
  font-size: 2vh;
  font-weight: 500;
}

.docInfo {
  font-size: 1.3vh;
  font-weight: 500;
  text-align: right;
}

#prescript-form {
  margin: 2vh 2.5vh;
}

.form-input {
  display: flex;
}

label {
  font-weight: 500;
  margin-right: 1vh;
}

input, select, textarea {
  font-family: 'Roboto', sans-serif;
}

.form-input> input {
  background-color: var(--background-1);
  border: none;
  border-bottom: 1px solid black;
  font-size: 1.5vh;
  margin-bottom: 2vh;
  flex-grow: 1;
}

*:focus {
  outline: none;
}

#medication {
  background-color: var(--background-1);
  border: none;
  border-bottom: 1px solid black;
  font-size: 1.5vh;
  margin-bottom: 2vh;
  width: 100%;
}

#medication > option {
  background-color: var(--background-1);

  font-size: 1.5vh;
  flex-grow: 1;
}

select:disabled, textarea:read-only, input:read-only {
  color: black;
  opacity: 1;
  font-family: 'Roboto', sans-serif;
}

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

#notes {
  border: none;
  font-size: 1.6vh;
  margin-top: 0.5vh;
  margin-bottom: 1vh;
  height: 20vh;
  width: 100%;
  resize: none;
  background-color: #F1EDE9;
}

#bottom-form {
  display: flex;
  justify-content: space-between;
}

.date {
  margin-top: 0.5vh;
  font-weight: 500;
}

.signature-input > label {
  padding: 0.5vh 1vh 0;
  margin: 0;
}

#sign {
  font-family: 'Pacifico', cursive;
  font-weight: 500;
  font-size: 1.5vh;
  width: 18vh;
}

#submit-button {
  position: absolute;
  left: 50%;
  transform: translate(-50%);
  background-color: #333;
  border: none;
  border-radius: 0.3vh;
  color: white;
  font-family: 'Roboto', sans-serif;
  font-size: 1.5vh;
  padding: 0.5vh 2vh;
  margin: 2vh 0;
}

#submit-button:hover {
  cursor: pointer;
  background-color: #555;
}

App.tsx

import React, {useState, useEffect} from 'react';
import './App.css'
import {debugData} from "../utils/debugData";
import { useVisibility } from '../providers/VisibilityProvider';
import Form from './Form';
import Header from './Header';
import { useNuiEvent } from '../hooks/useNuiEvent';
import { formatDate } from '../utils/formatString';

export interface IFormData {
  patient: string;
  medication: string;
  dosage: string;
  notes: string;
  signature: string;
}

export interface Medication {
  item: string;
  label: string;
}

interface DocData {
  name: string;
  phone: string;
}

interface IPrescriptData {
  docInfo: DocData;
  formInfo: IFormData | null;
  createDate: string;
  isReadOnly: boolean;
}

debugData([
  {
    action: 'setupForm',
    data: {
      docInfo: {
        name: "Dr Glowie",
        phone: "123-456-7889"
      },
      medInfo: [
        {item: "amoxicillin", label: "Amoxicillin"},
        {item: "hydromorphone", label: "Hydromorphone"},
        {item: "oxycodone", label: "Oxycodone"},
      ],
      unixTime: 1683869960,
    },
  }
])

debugData([
  {
    action: 'setupReadOnly',
    data: {
      docInfo: {
        name: "Dr Glowie",
        phone: "123-456-789",
      },
      formInfo: {
        patient: "Jin Pain",
        medication: "Hydromorphone",
        dosage: "32",
        notes: "Some notes here :)",
        signature: "Super Cool Signature",
      },
      unixTime: 1683869960,
    },
  }
])

const App: React.FC = () => {
  const { visible, setVisible } = useVisibility();
  const [medList, setMedList] = useState<Medication[]>([]);
  const [prescriptData, setPrescriptData] = useState<IPrescriptData>({
    docInfo: {name: "", phone: ""},
    formInfo: null,
    createDate: "",
    isReadOnly: true,
  })

  useNuiEvent("setupForm", (data: {docInfo: DocData, medInfo: Medication[], unixTime: number}) => {
    const formattedDate = formatDate(data.unixTime);
    setPrescriptData(prevData => {
      return {
        ...prevData,
        docInfo: data.docInfo,
        formInfo: null,
        createDate: formattedDate,
        isReadOnly: false,
      }
    })
    setMedList(data.medInfo);
    setVisible(true);
  })

  useNuiEvent("setupReadOnly", (data: {docInfo: DocData, formInfo: IFormData, unixTime: number}) => {
    const formattedDate = formatDate(data.unixTime);
    setPrescriptData(prevData => {
      return {
        ...prevData,
        docInfo: data.docInfo,
        formInfo: data.formInfo,
        createDate: formattedDate,
        isReadOnly: true,
      }
    })
    setVisible(true);
  })
    
  return (
    <div id="container">
      <div className="notepad-top"></div>
      <div id="prescript-container">
        <Header 
          name={prescriptData.docInfo.name}
          phone={prescriptData.docInfo.phone}
        />
        <Form
          medList={medList}
          createDate={prescriptData.createDate}
          prescript={prescriptData.formInfo}
          isReadOnly={prescriptData.isReadOnly}
        />
      </div>
    </div>
  );
}

export default App;


Form.tsx

import React, {useEffect, useState} from 'react';
import { Medication, IFormData } from './App';
import { useVisibility } from '../providers/VisibilityProvider';
import {fetchNui} from "../utils/fetchNui";

interface FormProps {
    medList: Medication[] | null;
    prescript: IFormData | null;
    createDate: string;
    isReadOnly: boolean;
}

const Form = ({medList, prescript, createDate, isReadOnly}: FormProps) => {
    const { visible, setVisible } = useVisibility();
    const [formData, setFormData] = useState({
        patient: "", 
        medication: "",
        dosage: "",
        notes: "",
        signature: "",
    });
    
    const handleInputChange = (e:React.ChangeEvent<any>): void => {
        setFormData(prevData => {
            return {
                ...prevData,
                [e.target.name]: e.target.value
            }
        })
    }
    
    const handleReset = () => {
        setFormData({
            patient: "", 
            medication: "",
            dosage: "",
            notes: "",
            signature: "",
        })
    }

    const handleSubmit = () => {
        fetchNui<{success: boolean}>("submit", formData).then(data => {
            if (data.success) {
                handleReset();
            }
        });
    }

    useEffect(() => {
        if (!visible) {
            handleReset();
        }
    }, [visible])

    return (
        <form id="prescript-form">
            <div className="form-input">
                <label htmlFor="patient">Patient Name: </label>
                <input id="patient" type="text" onChange={handleInputChange} value={prescript?.patient || formData.patient} name="patient" readOnly={isReadOnly}/>
            </div>
            <div className="form-input">
                <label htmlFor="medication">Rx: </label>
                <select id="medication" onChange={handleInputChange} value={formData.medication} name="medication" disabled={isReadOnly}>
                    <option value="">{prescript?.medication || "Select Medication"}</option>
                    {medList && medList.map((option) => (
                        <option key={option.item} value={option.item}>{option.label}</option>
                    ))}
                </select>
            </div>
            <div className="form-input">
                <label htmlFor="doses">Dosages #: </label>
                <input id="doses" type="number" onChange={handleInputChange} value={prescript?.dosage || formData.dosage} name="dosage" disabled={isReadOnly}/>
            </div>

            <label htmlFor="notes">Additional Notes:</label>
            <br />
            <textarea id="notes" onChange={handleInputChange} value={prescript?.notes || formData.notes} name="notes" disabled={isReadOnly} />

            <div id="bottom-form">
                <div className="form-input signature-input">
                    <label htmlFor="sign">Signature: </label>
                    <input id="sign" type="text" onChange={handleInputChange} value={prescript?.signature || formData.signature} name="signature" disabled={isReadOnly} />
                </div>
                <div className="date">Date: {createDate}</div>
            </div>

            {isReadOnly || <button id="submit-button" type="button" onClick={handleSubmit} disabled={isReadOnly}>Submit</button>}
        </form>
    )
}

export default Form

Header.tsx

import { formatPhone } from "../utils/formatString"
const Header = ({name, phone}: {name: string, phone: string}) => {
    return (
        <div id="header">
            <div className="prescription-icon">
                <i className="fa-solid fa-prescription fa-lg"></i>
                <span className="header-text">Prescription</span>
            </div>
            <div className="docInfo">
                <div className="docName">{name}</div>
                <div className="docPhone">{formatPhone(phone)}</div>
            </div>
        </div>
    )
}

export default Header