diff --git a/README.md b/README.md index feab9681..95338123 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This is a web interface that can be used to manage the settings and configuratio The app is implemented with React. To get started: -``` +```bash git clone https://github.com/althea-mesh/althea-dash cd althea-dash yarn @@ -18,3 +18,10 @@ The app is implemented with React. To get started: 2.) run ssh -L localhost:4877:localhost:4877 root@192.168.10.1 in terminal 3.) navigate to althea-dash repo and run yarn start + +### Formatting + +```bash +yarn +node_modules/.bin/prettier --write src/*.js src/**/*.js src/**/**/*.js +``` diff --git a/package.json b/package.json index 41e25466..2c8b8feb 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "node-sass": "^6.0.1", "npm": "^6.3.0", "popper.js": "^1.14.4", - "prettier": "1.14.0", + "prettier": "^1.14.0", "prop-types": "^15.6.2", "qrcode.react": "^0.8.0", "qrious": "^4.0.2", @@ -105,4 +105,4 @@ "glob-all": "^3.1.0", "purgecss-webpack-plugin": "^1.6.0" } -} \ No newline at end of file +} diff --git a/src/AdvancedSettings/AdvancedDebugging.js b/src/AdvancedSettings/AdvancedDebugging.js index 3ef9a08f..a4d9548a 100644 --- a/src/AdvancedSettings/AdvancedDebugging.js +++ b/src/AdvancedSettings/AdvancedDebugging.js @@ -73,25 +73,24 @@ const AdvancedDebugging = () => { ))} - {!isGateway && - (haveProblem && ( -
-
{t("suggestedAction")}
- {hasNeighborRoute ? ( - hasExitRoute ? ( - selectedExit ? ( -

{t("exitProblem")}

- ) : ( -

{t("noExit")}

- ) + {!isGateway && haveProblem && ( +
+
{t("suggestedAction")}
+ {hasNeighborRoute ? ( + hasExitRoute ? ( + selectedExit ? ( +

{t("exitProblem")}

) : ( -

{t("noNeighborExit")}

+

{t("noExit")}

) ) : ( -

{t("noNeighbor")}

- )} -
- ))} +

{t("noNeighborExit")}

+ ) + ) : ( +

{t("noNeighbor")}

+ )} +
+ )} ); }; diff --git a/src/AdvancedSettings/BandwidthLimit.js b/src/AdvancedSettings/BandwidthLimit.js index 1d83c039..03372741 100644 --- a/src/AdvancedSettings/BandwidthLimit.js +++ b/src/AdvancedSettings/BandwidthLimit.js @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { Alert, @@ -11,12 +11,11 @@ import { InputGroupAddon, InputGroupText, Label, - Progress, + Progress } from "reactstrap"; import { get, post } from "store"; import { Card } from "ui"; - const BandwidthLimit = () => { const [t] = useTranslation(); const [limit, setLimit] = useState(null); @@ -58,7 +57,7 @@ const BandwidthLimit = () => { } } - const submit = async (e) => { + const submit = async e => { e.preventDefault(); setLoading(true); @@ -96,7 +95,7 @@ const BandwidthLimit = () => { name="bandwidth" id="selfLimitSpeed" placeholder={t("enterSpeed")} - onChange={(e) => { + onChange={e => { setLimit(e.target.value); setUnsavedChanges(true); }} @@ -109,7 +108,7 @@ const BandwidthLimit = () => { style={{ background: "#F8F9FA", fontSize: 14, - color: "#888", + color: "#888" }} > Mbps diff --git a/src/AdvancedSettings/Blockchain.js b/src/AdvancedSettings/Blockchain.js index c69bdc75..2588c0de 100644 --- a/src/AdvancedSettings/Blockchain.js +++ b/src/AdvancedSettings/Blockchain.js @@ -18,23 +18,20 @@ const Blockchain = () => { const [{ blockchain }, dispatch] = useStore(); const [newBlockchain, setBlockchain] = useState(blockchain); - useEffect( - () => { - const controller = new AbortController(); - const signal = controller.signal; - (async () => { - try { - const blockchain = await get("/blockchain/get", true, 5000, signal); - if (!(blockchain instanceof Error)) { - dispatch({ type: "blockchain", blockchain }); - } - } catch (e) {} - })(); + useEffect(() => { + const controller = new AbortController(); + const signal = controller.signal; + (async () => { + try { + const blockchain = await get("/blockchain/get", true, 5000, signal); + if (!(blockchain instanceof Error)) { + dispatch({ type: "blockchain", blockchain }); + } + } catch (e) {} + })(); - return () => controller.abort(); - }, - [dispatch] - ); + return () => controller.abort(); + }, [dispatch]); if (!blockchain || !newBlockchain) return null; diff --git a/src/AdvancedSettings/DaoFee.js b/src/AdvancedSettings/DaoFee.js index 7f4c42ad..b01f598c 100644 --- a/src/AdvancedSettings/DaoFee.js +++ b/src/AdvancedSettings/DaoFee.js @@ -56,15 +56,12 @@ const DaoFee = ({ readonly = false }) => { } }; - useEffect( - () => { - const controller = new AbortController(); - const signal = controller.signal; - getDaoFee(signal); - return () => controller.abort(); - }, - [getDaoFee] - ); + useEffect(() => { + const controller = new AbortController(); + const signal = controller.signal; + getDaoFee(signal); + return () => controller.abort(); + }, [getDaoFee]); const submit = e => { e.preventDefault(); diff --git a/src/AdvancedSettings/NetworkOrganizer.js b/src/AdvancedSettings/NetworkOrganizer.js index a062233f..71577676 100644 --- a/src/AdvancedSettings/NetworkOrganizer.js +++ b/src/AdvancedSettings/NetworkOrganizer.js @@ -157,7 +157,11 @@ const NetworkOrganizer = () => { - diff --git a/src/AdvancedSettings/NodeInformation.js b/src/AdvancedSettings/NodeInformation.js index b3ce2d44..21ca6823 100644 --- a/src/AdvancedSettings/NodeInformation.js +++ b/src/AdvancedSettings/NodeInformation.js @@ -21,24 +21,21 @@ const NodeInformation = () => { const [copied, setCopied] = useState(""); const [{ address, meshIp, wgPublicKey }, dispatch] = useStore(); - useEffect( - () => { - const init = async () => { - try { - const { meshIp } = await get("/mesh_ip"); - dispatch({ type: "meshIp", meshIp }); + useEffect(() => { + const init = async () => { + try { + const { meshIp } = await get("/mesh_ip"); + dispatch({ type: "meshIp", meshIp }); - const wgPublicKey = await get("/wg_public_key"); - dispatch({ type: "wgPublicKey", wgPublicKey }); - } catch (e) { - console.log(e); - } - }; + const wgPublicKey = await get("/wg_public_key"); + dispatch({ type: "wgPublicKey", wgPublicKey }); + } catch (e) { + console.log(e); + } + }; - init(); - }, - [dispatch] - ); + init(); + }, [dispatch]); const toggleQR = v => { if (qr === v) return setQR(""); diff --git a/src/AdvancedSettings/RemoteLogging.js b/src/AdvancedSettings/RemoteLogging.js index 5ef88de5..7ab28f45 100644 --- a/src/AdvancedSettings/RemoteLogging.js +++ b/src/AdvancedSettings/RemoteLogging.js @@ -16,18 +16,18 @@ const RemoteLogging = () => { const [success, setSuccess] = useState(false); const [nowWaiting, setNowWaiting] = useState(false); - useEffect( + useEffect(() => { + if (level && !newLevel) setNewLevel(level); + return; + }, [level, newLevel]); + + useInterval( () => { - if (level && !newLevel) setNewLevel(level); - return; + if (nowWaiting) dispatch({ type: "keepWaiting" }); }, - [level, newLevel] + waiting ? 1000 : null ); - useInterval(() => { - if (nowWaiting) dispatch({ type: "keepWaiting" }); - }, waiting ? 1000 : null); - useRemoteLogging(); const check = async e => { diff --git a/src/AdvancedSettings/index.js b/src/AdvancedSettings/index.js index 1b5ba55c..848cd41c 100644 --- a/src/AdvancedSettings/index.js +++ b/src/AdvancedSettings/index.js @@ -1,3 +1,4 @@ +/* eslint-disable import/no-anonymous-default-export */ import React from "react"; import { useTranslation } from "react-i18next"; diff --git a/src/Deposit.js b/src/Deposit.js index d90dcde2..93362732 100644 --- a/src/Deposit.js +++ b/src/Deposit.js @@ -9,7 +9,7 @@ import { Input, FormGroup, Label, - InputGroup, + InputGroup } from "reactstrap"; import QR from "qrcode.react"; import { CopyToClipboard } from "react-copy-to-clipboard"; @@ -68,7 +68,7 @@ function user_info_forum( type="text" defaultValue={billingDetails.user_first_name} placeholder="First Name" - onChange={(e) => { + onChange={e => { let local = billingDetails; local.user_first_name = e.target.value; setBillingDetails(local); @@ -83,7 +83,7 @@ function user_info_forum( type="text" defaultValue={billingDetails.user_last_name} placeholder="Last Name" - onChange={(e) => { + onChange={e => { let local = billingDetails; local.user_last_name = e.target.value; setBillingDetails(local); @@ -101,7 +101,7 @@ function user_info_forum( type="text" defaultValue={email} placeholder="User Email" - onChange={(e) => setEmail(e.target.value)} + onChange={e => setEmail(e.target.value)} /> @@ -115,7 +115,7 @@ function user_info_forum( inputComponent={SmartInput} placeholder="User Phonenumber" value={phone} - onChange={(p) => setPhone(p)} + onChange={p => setPhone(p)} /> @@ -128,7 +128,7 @@ function user_info_forum( type="text" placeholder="Street" defaultValue={billingDetails.mailing_address.street} - onChange={(e) => { + onChange={e => { let local = billingDetails; local.mailing_address.street = e.target.value; setBillingDetails(local); @@ -144,7 +144,7 @@ function user_info_forum( type="text" defaultValue={billingDetails.mailing_address.postal_code} placeholder="Postal Code" - onChange={(e) => { + onChange={e => { let local = billingDetails; local.mailing_address.postal_code = e.target.value; setBillingDetails(local); @@ -159,7 +159,7 @@ function user_info_forum( type="text" defaultValue={billingDetails.mailing_address.city} placeholder="City" - onChange={(e) => { + onChange={e => { let local = billingDetails; local.mailing_address.city = e.target.value; setBillingDetails(local); @@ -174,7 +174,7 @@ function user_info_forum( type="text" defaultValue={billingDetails.mailing_address.state} placeholder="State" - onChange={(e) => { + onChange={e => { let local = billingDetails; local.mailing_address.state = e.target.value; setBillingDetails(local); @@ -189,7 +189,7 @@ function user_info_forum( type="select" defaultValue={billingDetails.mailing_address.country} placeholder="Country" - onChange={(e) => { + onChange={e => { let local = billingDetails; local.mailing_address.country = e.target.value; setBillingDetails(local); @@ -212,7 +212,7 @@ function user_info_forum(
diff --git a/src/RouterSettings/Wifi.js b/src/RouterSettings/Wifi.js index af46e924..e68dcc19 100644 --- a/src/RouterSettings/Wifi.js +++ b/src/RouterSettings/Wifi.js @@ -15,9 +15,12 @@ const Wifi = () => { const [{ wifiSettings, waiting }, dispatch] = useStore(); const [wifiError, loading] = useWifiSettings(); - useInterval(() => { - if (wifiWaiting) dispatch({ type: "keepWaiting" }); - }, waiting ? 1000 : null); + useInterval( + () => { + if (wifiWaiting) dispatch({ type: "keepWaiting" }); + }, + waiting ? 1000 : null + ); if (!wifiSettings || !wifiSettings.length) if (loading && !error) @@ -39,7 +42,7 @@ const Wifi = () => { let channel = parseInt(setting.device.channel, 10); //convert from string to boolean: '0' === enabled = false, '1' === disabled = true - let disabled = setting.device.disabled === '1'; + let disabled = setting.device.disabled === "1"; data.push({ WifiChannel: { radio, channel } }); data.push({ WifiSsid: { radio, ssid } }); @@ -66,19 +69,18 @@ const Wifi = () => { // dispatch({ type: "startWaiting", waiting: 120 }); // dispatch({ type: "wifiChange" }); } - - } catch { } + } catch {} }; let valid = wifiSettings.reduce( - (a, b) => a && (b.ssid.length >= 8 && b.key != null && b.key.length >= 8), + (a, b) => a && b.ssid.length >= 8 && b.key != null && b.key.length >= 8, true ); return ( - +
{wifiSettings.map((_, i) => ( diff --git a/src/RouterSettings/WifiSettingsForm.js b/src/RouterSettings/WifiSettingsForm.js index 4e75635e..0e00523d 100644 --- a/src/RouterSettings/WifiSettingsForm.js +++ b/src/RouterSettings/WifiSettingsForm.js @@ -39,11 +39,10 @@ const WifiSettingsForm = ({ index }) => { }; const setDisabled = e => { - settings.device.disabled = e.target.checked ? '1' : '0'; + settings.device.disabled = e.target.checked ? "1" : "0"; saveSettings(); }; - return ( <>

{t(radioType)}

@@ -94,10 +93,9 @@ const WifiSettingsForm = ({ index }) => { name="dis" label="" onChange={setDisabled} - checked={settings.device.disabled === '1'} + checked={settings.device.disabled === "1"} /> - ); diff --git a/src/SellingBandwidth/Price.js b/src/SellingBandwidth/Price.js index deb44ade..75860de9 100644 --- a/src/SellingBandwidth/Price.js +++ b/src/SellingBandwidth/Price.js @@ -11,7 +11,7 @@ import { InputGroupAddon, InputGroupText, Label, - Progress, + Progress } from "reactstrap"; import { get, post } from "store"; import useInterval from "hooks/useInterval"; @@ -84,7 +84,7 @@ const Price = () => { useInterval(getPrice, 5000); - const submit = async (e) => { + const submit = async e => { e.preventDefault(); setLoading(true); @@ -114,7 +114,7 @@ const Price = () => { } catch {} }; - const changePrice = (e) => { + const changePrice = e => { setSuccess(false); setNewPrice(e.target.value); }; @@ -146,7 +146,7 @@ const Price = () => { style={{ background: "#F8F9FA", fontSize: 14, - color: "#888", + color: "#888" }} > {symbol_or_star} / GB diff --git a/src/SellingBandwidth/RelaySettings.js b/src/SellingBandwidth/RelaySettings.js index 7bf4d08f..5d322ecb 100644 --- a/src/SellingBandwidth/RelaySettings.js +++ b/src/SellingBandwidth/RelaySettings.js @@ -44,17 +44,14 @@ const RelaySettings = () => { useInterval(getNeighbors, 10000); - useEffect( - () => { - const controller = new AbortController(); - const signal = controller.signal; + useEffect(() => { + const controller = new AbortController(); + const signal = controller.signal; - getNeighbors(signal); + getNeighbors(signal); - return () => controller.abort(); - }, - [getNeighbors] - ); + return () => controller.abort(); + }, [getNeighbors]); const toggle = () => setOpen(!open); diff --git a/src/SellingBandwidth/RevenueHistory.js b/src/SellingBandwidth/RevenueHistory.js index 12bbfff6..703139fc 100644 --- a/src/SellingBandwidth/RevenueHistory.js +++ b/src/SellingBandwidth/RevenueHistory.js @@ -24,14 +24,14 @@ const RevenueHistory = () => { const periods = { d: t("daily"), w: t("weekly"), - m: t("monthly"), + m: t("monthly") }; const limit = { h: 24, d: 10, w: 4, - m: 12, + m: 12 }[period]; useEffect(() => setPage(1), [period]); @@ -90,7 +90,7 @@ const RevenueHistory = () => { style={{ whiteSpace: "nowrap", fontSize: 16, - color: "#666", + color: "#666" }} className="mr-2 d-flex" > @@ -99,9 +99,9 @@ const RevenueHistory = () => { type="select" style={{ color: "#666" }} value={period} - onChange={(e) => setPeriod(e.target.value)} + onChange={e => setPeriod(e.target.value)} > - {Object.keys(periods).map((p) => ( + {Object.keys(periods).map(p => ( @@ -120,7 +120,7 @@ const RevenueHistory = () => { - {rows.map((r) => ( + {rows.map(r => ( {r.period} {r.usage} diff --git a/src/Settings/Exits/AddExitForm.js b/src/Settings/Exits/AddExitForm.js index b7b961c6..84d84a0f 100644 --- a/src/Settings/Exits/AddExitForm.js +++ b/src/Settings/Exits/AddExitForm.js @@ -44,83 +44,83 @@ const AddExitForm = ({ setAdding, setFillForm }) => { }; return ( - - {loading && } - - {success ? ( - <> - - - - ) : ( - <> - - - setIdentifier(e.target.value)} - placeholder={t("identifier")} - autoFocus - /> - - - - setDescription(e.target.value)} - placeholder={t("description")} - autoFocus - /> - - - - setMeshIp(e.target.value)} - placeholder={t("meshIp")} - autoFocus - /> - - - - setEthAddress(e.target.value)} - placeholder={t("ethereumAddress")} - autoFocus - /> - - - - setWgPubKey(e.target.value)} - placeholder={t("wireguardPublicKey")} - autoFocus - /> - - - - setRegistrationPort(e.target.value)} - placeholder={t("registrationPort")} - autoFocus - /> - - - - - )} - +
+ {loading && } + + {success ? ( + <> + + + + ) : ( + <> + + + setIdentifier(e.target.value)} + placeholder={t("identifier")} + autoFocus + /> + + + + setDescription(e.target.value)} + placeholder={t("description")} + autoFocus + /> + + + + setMeshIp(e.target.value)} + placeholder={t("meshIp")} + autoFocus + /> + + + + setEthAddress(e.target.value)} + placeholder={t("ethereumAddress")} + autoFocus + /> + + + + setWgPubKey(e.target.value)} + placeholder={t("wireguardPublicKey")} + autoFocus + /> + + + + setRegistrationPort(e.target.value)} + placeholder={t("registrationPort")} + autoFocus + /> + + + + + )} + ); -} +}; export default AddExitForm; diff --git a/src/Settings/Exits/CodeForm.js b/src/Settings/Exits/CodeForm.js index 829093c2..a8a35678 100644 --- a/src/Settings/Exits/CodeForm.js +++ b/src/Settings/Exits/CodeForm.js @@ -13,17 +13,14 @@ const CodeForm = ({ nickname, registered, targetLength, setOpen }) => { let { verifyExit } = useContext(ExitsContext); - useEffect( - () => { - const timer = setTimeout(() => { - setWaiting(false); - setExpired(true); - }, 12000); + useEffect(() => { + const timer = setTimeout(() => { + setWaiting(false); + setExpired(true); + }, 12000); - return () => clearTimeout(timer); - }, - [code] - ); + return () => clearTimeout(timer); + }, [code]); let handleCode = e => { let { value } = e.target; @@ -58,12 +55,11 @@ const CodeForm = ({ nickname, registered, targetLength, setOpen }) => { ) : ( <> - {expired && - code.length === targetLength && ( - - {t("registrationFailed")} - - )} + {expired && code.length === targetLength && ( + + {t("registrationFailed")} + + )} { return ( (state !== "New" && state !== "Disabled" && - (exit.exitSettings.generalDetails && - exit.exitSettings.generalDetails.exitCurrency === blockchain)) || + exit.exitSettings.generalDetails && + exit.exitSettings.generalDetails.exitCurrency === blockchain) || state === "Denied" ); }) @@ -35,27 +35,32 @@ const ExitList = ({ setOpen, select }) => { return (
- {adding ? : exits.length ? ( + {adding ? ( + + ) : exits.length ? ( <> -

{t("selectNode")}

- - {exits.map(exit => ( - select(exit)} - /> - ))} - - +

{t("selectNode")}

+ + {exits.map(exit => ( + select(exit)} + /> + ))} + + ) : ( <> - {t("noExits")} - + {t("noExits")} + )} -
); }; diff --git a/src/Settings/Exits/ExitListItem.js b/src/Settings/Exits/ExitListItem.js index 650550cf..846ced60 100644 --- a/src/Settings/Exits/ExitListItem.js +++ b/src/Settings/Exits/ExitListItem.js @@ -1,3 +1,4 @@ +/* eslint-disable import/no-anonymous-default-export */ import React from "react"; import { useTranslation } from "react-i18next"; import { ListGroupItem } from "reactstrap"; diff --git a/src/Settings/Exits/ExitNodeSetup.js b/src/Settings/Exits/ExitNodeSetup.js index f3580746..0d88654a 100644 --- a/src/Settings/Exits/ExitNodeSetup.js +++ b/src/Settings/Exits/ExitNodeSetup.js @@ -59,7 +59,7 @@ const ExitNodeSetup = ({ open, setOpen }) => { const select = exit => { let verifMode; - + if (exit.exitSettings.generalDetails) verifMode = exit.exitSettings.generalDetails.verifMode; @@ -190,22 +190,25 @@ const ExitNodeSetup = ({ open, setOpen }) => { ); case "Phone": return ( - + ); default: return null; } })() ))} - {!resetting.length && - (pending || registered) && ( - - )} + {!resetting.length && (pending || registered) && ( + + )} )} diff --git a/src/Settings/Exits/JsonForm.js b/src/Settings/Exits/JsonForm.js index e17d1efd..eb77397c 100644 --- a/src/Settings/Exits/JsonForm.js +++ b/src/Settings/Exits/JsonForm.js @@ -27,40 +27,40 @@ const JsonForm = ({ setAdding, setPasteJson }) => { }; return ( -
- {loading && } - - {success ? ( - <> - - - - ) : ( - <> - - - setJson(e.target.value)} - placeholder={t("exitJson")} - autoFocus - rows={8} - /> - - - - - )} - - ) -} +
+ {loading && } + + {success ? ( + <> + + + + ) : ( + <> + + + setJson(e.target.value)} + placeholder={t("exitJson")} + autoFocus + rows={8} + /> + + + + + )} + + ); +}; export default JsonForm; diff --git a/src/Settings/Exits/SelectedExit.js b/src/Settings/Exits/SelectedExit.js index 128d5b46..28228875 100644 --- a/src/Settings/Exits/SelectedExit.js +++ b/src/Settings/Exits/SelectedExit.js @@ -1,3 +1,4 @@ +/* eslint-disable import/no-anonymous-default-export */ import React, { useContext } from "react"; import { useTranslation } from "react-i18next"; import { Button } from "reactstrap"; diff --git a/src/Settings/Exits/index.js b/src/Settings/Exits/index.js index 37e95602..9425e261 100644 --- a/src/Settings/Exits/index.js +++ b/src/Settings/Exits/index.js @@ -20,7 +20,7 @@ const Exits = () => { const [{ exits, resetting, selectedExit }, dispatch] = useStore(); - const getExits = async (signal) => { + const getExits = async signal => { if (!signal) { const controller = new AbortController(); signal = controller.signal; @@ -43,14 +43,14 @@ const Exits = () => { } catch {} }; - const resetExit = async (exit) => { + const resetExit = async exit => { const { nickname } = exit; dispatch({ type: "reset", nickname, resetting }); await post(`/exits/${nickname}/reset`); getExits(); }; - const selectExit = async (nickname) => { + const selectExit = async nickname => { await post(`/exits/${nickname}/select`); getExits(); }; @@ -94,7 +94,7 @@ const Exits = () => { registerExit, resetExit, selectExit, - verifyExit, + verifyExit }; return ( diff --git a/src/Settings/Firmware/UpdateFirmware.js b/src/Settings/Firmware/UpdateFirmware.js index 9bf9cb30..a8546831 100644 --- a/src/Settings/Firmware/UpdateFirmware.js +++ b/src/Settings/Firmware/UpdateFirmware.js @@ -1,3 +1,4 @@ +/* eslint-disable import/no-anonymous-default-export */ import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { Alert, Button, Modal, ModalBody, Progress } from "reactstrap"; @@ -33,17 +34,20 @@ export default ({ open, setOpen }) => { } }; - useInterval(() => { - if (firmwareUpgrading) { - dispatch({ type: "keepWaiting" }); - if (!waiting && !firmwareUpgraded) { - setFirmwareUpgrading(false); - setWarning(t("firmwareNoUpdate")); - dispatch({ type: "firmwareUpgrading", firmwareUpgrading: false }); - dispatch({ type: "warning", warning: true }); + useInterval( + () => { + if (firmwareUpgrading) { + dispatch({ type: "keepWaiting" }); + if (!waiting && !firmwareUpgraded) { + setFirmwareUpgrading(false); + setWarning(t("firmwareNoUpdate")); + dispatch({ type: "firmwareUpgrading", firmwareUpgrading: false }); + dispatch({ type: "warning", warning: true }); + } } - } - }, waiting ? 1000 : null); + }, + waiting ? 1000 : null + ); useEffect(() => { const firmwareUpgraded = diff --git a/src/Settings/Notifications.js b/src/Settings/Notifications.js index 048ad603..29389258 100644 --- a/src/Settings/Notifications.js +++ b/src/Settings/Notifications.js @@ -1,3 +1,4 @@ +/* eslint-disable import/no-anonymous-default-export */ import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { @@ -8,7 +9,7 @@ import { FormGroup, CustomInput, Input, - Label, + Label } from "reactstrap"; import { get, post } from "store"; import PhoneInput from "react-phone-number-input"; @@ -46,16 +47,16 @@ export default ({ balance, symbol }) => { let validEmail = !email || isValidEmail(email); let validPhone = !phone || isValidPhoneNumber(phone); - let handleEmail = (e) => { + let handleEmail = e => { let { value } = e.target; setEmail(value); }; - let handlePhone = (value) => { + let handlePhone = value => { setPhone(value); }; - let submit = async (e) => { + let submit = async e => { e.preventDefault(); if (validEmail && validPhone) { try { @@ -108,7 +109,7 @@ export default ({ balance, symbol }) => { flags={Flags} placeholder={t("phoneNumber")} value={phone} - onChange={(p) => handlePhone(p)} + onChange={p => handlePhone(p)} /> diff --git a/src/Settings/RouterNickname/index.js b/src/Settings/RouterNickname/index.js index 4d2eaac8..e66f5fc0 100644 --- a/src/Settings/RouterNickname/index.js +++ b/src/Settings/RouterNickname/index.js @@ -22,13 +22,10 @@ const Nickname = () => { const [newNickname, setNewNickname] = useState(nickname || ""); const [loading] = useNickname(); - useEffect( - () => { - nickname && setNewNickname(nickname); - return; - }, - [nickname] - ); + useEffect(() => { + nickname && setNewNickname(nickname); + return; + }, [nickname]); const update = e => { setNewNickname(e.target.value); diff --git a/src/Settings/index.js b/src/Settings/index.js index b0015712..bf8eecea 100644 --- a/src/Settings/index.js +++ b/src/Settings/index.js @@ -1,3 +1,4 @@ +/* eslint-disable import/no-anonymous-default-export */ import React from "react"; import { useTranslation } from "react-i18next"; diff --git a/src/WalletManagement/ImportPrivateKey.js b/src/WalletManagement/ImportPrivateKey.js index 83d4e14e..a9077bdd 100644 --- a/src/WalletManagement/ImportPrivateKey.js +++ b/src/WalletManagement/ImportPrivateKey.js @@ -39,7 +39,7 @@ const ImportPrivateKey = () => { return; }, []); - const save = async (e) => { + const save = async e => { e.preventDefault(); try { @@ -50,7 +50,7 @@ const ImportPrivateKey = () => { } }; - const confirm = (e) => { + const confirm = e => { e.preventDefault(); setConfirming(true); }; @@ -107,7 +107,7 @@ const ImportPrivateKey = () => { className="mr-3 mb-2" id="privateKey" name="privateKey" - onChange={(e) => setPrivateKey(e.target.value)} + onChange={e => setPrivateKey(e.target.value)} value={privateKey} style={{ width: 350 }} /> diff --git a/src/Withdraw.js b/src/Withdraw.js index 3288304e..021c93a9 100644 --- a/src/Withdraw.js +++ b/src/Withdraw.js @@ -12,7 +12,7 @@ import { Label, Modal, ModalHeader, - ModalBody, + ModalBody } from "reactstrap"; import { Error, toEth, toWei, txLink } from "utils"; import { isAddress } from "ethereum-address"; @@ -29,7 +29,7 @@ const Withdraw = ({ open, setOpen }) => { const [{ balance, blockchain, symbol }] = useStore(); - const onSubmit = async (e) => { + const onSubmit = async e => { e.preventDefault(); let txid; try { @@ -65,7 +65,7 @@ const Withdraw = ({ open, setOpen }) => { setTxid(null); }; - const withdrawAll = (e) => { + const withdrawAll = e => { e.preventDefault(); setAmount(balanceEth); @@ -98,7 +98,7 @@ const Withdraw = ({ open, setOpen }) => { ) : (

@@ -124,7 +124,7 @@ const Withdraw = ({ open, setOpen }) => { type="text" name="address" placeholder={t("recipientAddress")} - onChange={(e) => setAddress(e.target.value)} + onChange={e => setAddress(e.target.value)} value={address} valid={addressValid} invalid={!!(address && !addressValid)} @@ -145,7 +145,7 @@ const Withdraw = ({ open, setOpen }) => { label={t("to")} name="amount" placeholder={0} - onChange={(e) => setAmount(e.target.value)} + onChange={e => setAmount(e.target.value)} value={amount} valid={amountValid} invalid={!!(amount && !amountValid)} @@ -155,7 +155,7 @@ const Withdraw = ({ open, setOpen }) => { style={{ background: "#F8F9FA", fontSize: 14, - color: "#888", + color: "#888" }} > {symbol} @@ -175,7 +175,7 @@ const Withdraw = ({ open, setOpen }) => { display: "flex", margin: -20, marginTop: 0, - padding: 10, + padding: 10 }} /> diff --git a/src/hooks/useDebounce.js b/src/hooks/useDebounce.js index 439d1017..645d7fc8 100644 --- a/src/hooks/useDebounce.js +++ b/src/hooks/useDebounce.js @@ -3,18 +3,15 @@ import { useEffect, useState } from "react"; export function useDebounce(value, delay) { const [debouncedValue, setDebouncedValue] = useState(value); - useEffect( - () => { - const handler = setTimeout(() => { - setDebouncedValue(value); - }, delay); + useEffect(() => { + const handler = setTimeout(() => { + setDebouncedValue(value); + }, delay); - return () => { - clearTimeout(handler); - }; - }, - [delay, value] - ); + return () => { + clearTimeout(handler); + }; + }, [delay, value]); return debouncedValue; } diff --git a/src/hooks/useInterval.js b/src/hooks/useInterval.js index 6e3fe8f7..00ffc246 100644 --- a/src/hooks/useInterval.js +++ b/src/hooks/useInterval.js @@ -8,22 +8,19 @@ export default function useInterval(callback, delay) { savedCallback.current = callback; }); - useEffect( - () => { - const controller = new AbortController(); - const signal = controller.signal; + useEffect(() => { + const controller = new AbortController(); + const signal = controller.signal; + savedCallback.current(signal); + function tick() { savedCallback.current(signal); - function tick() { - savedCallback.current(signal); - } + } - let id = setInterval(tick, delay); - return () => { - clearInterval(id); - controller.abort(); - }; - }, - [delay] - ); + let id = setInterval(tick, delay); + return () => { + clearInterval(id); + controller.abort(); + }; + }, [delay]); } diff --git a/src/hooks/useLightClientAP.js b/src/hooks/useLightClientAP.js index 3ae56b5c..ff26ceee 100644 --- a/src/hooks/useLightClientAP.js +++ b/src/hooks/useLightClientAP.js @@ -7,32 +7,29 @@ const useLightClientAP = () => { const [loading, setLoading] = useState(true); const [, dispatch] = useStore(); - useEffect( - () => { - const controller = new AbortController(); - const signal = controller.signal; - (async () => { - setLoading(true); + useEffect(() => { + const controller = new AbortController(); + const signal = controller.signal; + (async () => { + setLoading(true); - try { - let lightClientAP = await get( - "/interfaces/lightclient", - true, - 5000, - signal - ); - if (!(lightClientAP instanceof Error)) - dispatch({ type: "lightClientAP", lightClientAP }); - } catch { - return; - } + try { + let lightClientAP = await get( + "/interfaces/lightclient", + true, + 5000, + signal + ); + if (!(lightClientAP instanceof Error)) + dispatch({ type: "lightClientAP", lightClientAP }); + } catch { + return; + } - setLoading(false); - })(); - return () => controller.abort(); - }, - [dispatch] - ); + setLoading(false); + })(); + return () => controller.abort(); + }, [dispatch]); return [loading]; }; diff --git a/src/hooks/useMeshAP.js b/src/hooks/useMeshAP.js index 6dd6f4ed..5870007e 100644 --- a/src/hooks/useMeshAP.js +++ b/src/hooks/useMeshAP.js @@ -7,26 +7,23 @@ const useMeshAP = () => { const [loading, setLoading] = useState(true); const [, dispatch] = useStore(); - useEffect( - () => { - const controller = new AbortController(); - const signal = controller.signal; - (async () => { - setLoading(true); + useEffect(() => { + const controller = new AbortController(); + const signal = controller.signal; + (async () => { + setLoading(true); - try { - let meshAP = await get("/interfaces/mesh", true, 5000, signal); - if (!(meshAP instanceof Error)) dispatch({ type: "meshAP", meshAP }); - } catch { - return; - } + try { + let meshAP = await get("/interfaces/mesh", true, 5000, signal); + if (!(meshAP instanceof Error)) dispatch({ type: "meshAP", meshAP }); + } catch { + return; + } - setLoading(false); - })(); - return () => controller.abort(); - }, - [dispatch] - ); + setLoading(false); + })(); + return () => controller.abort(); + }, [dispatch]); return [loading]; }; diff --git a/src/hooks/useNickname.js b/src/hooks/useNickname.js index 54d260b0..3a4a1b12 100644 --- a/src/hooks/useNickname.js +++ b/src/hooks/useNickname.js @@ -7,27 +7,24 @@ const useNickname = () => { const [loading, setLoading] = useState(true); const [, dispatch] = useStore(); - useEffect( - () => { - const controller = new AbortController(); - const signal = controller.signal; - (async () => { - setLoading(true); + useEffect(() => { + const controller = new AbortController(); + const signal = controller.signal; + (async () => { + setLoading(true); - try { - let nickname = await get("/nickname/get", true, 5000, signal); - if (!(nickname instanceof Error)) - dispatch({ type: "nickname", nickname }); - } catch { - return; - } + try { + let nickname = await get("/nickname/get", true, 5000, signal); + if (!(nickname instanceof Error)) + dispatch({ type: "nickname", nickname }); + } catch { + return; + } - setLoading(false); - })(); - return () => controller.abort(); - }, - [dispatch] - ); + setLoading(false); + })(); + return () => controller.abort(); + }, [dispatch]); return [loading]; }; diff --git a/src/hooks/useRemoteAccess.js b/src/hooks/useRemoteAccess.js index 1f596c28..41dbce6a 100644 --- a/src/hooks/useRemoteAccess.js +++ b/src/hooks/useRemoteAccess.js @@ -7,27 +7,24 @@ const useRemoteAccess = () => { const [loading, setLoading] = useState(true); const [, dispatch] = useStore(); - useEffect( - () => { - const controller = new AbortController(); - const signal = controller.signal; - (async () => { - setLoading(true); + useEffect(() => { + const controller = new AbortController(); + const signal = controller.signal; + (async () => { + setLoading(true); - try { - let remoteAccess = await get("/remote_access", true, 5000, signal); - if (!(remoteAccess instanceof Error)) - dispatch({ type: "remoteAccess", remoteAccess }); - } catch { - return; - } + try { + let remoteAccess = await get("/remote_access", true, 5000, signal); + if (!(remoteAccess instanceof Error)) + dispatch({ type: "remoteAccess", remoteAccess }); + } catch { + return; + } - setLoading(false); - })(); - return () => controller.abort(); - }, - [dispatch] - ); + setLoading(false); + })(); + return () => controller.abort(); + }, [dispatch]); return [loading]; }; diff --git a/src/hooks/useRemoteLogging.js b/src/hooks/useRemoteLogging.js index 63430497..f648d214 100644 --- a/src/hooks/useRemoteLogging.js +++ b/src/hooks/useRemoteLogging.js @@ -7,35 +7,36 @@ const useRemoteLogging = () => { const [loading, setLoading] = useState(true); const [, dispatch] = useStore(); - useEffect( - () => { - const controller = new AbortController(); - const signal = controller.signal; - (async () => { - setLoading(true); - - try { - let remoteLogging = await get("/remote_logging/enabled", true, 5000, signal); - if (!(remoteLogging instanceof Error)) - dispatch({ type: "remoteLogging", remoteLogging }); - } catch { - return; - } - - try { - let level = await get("/remote_logging/level", true, 5000, signal); - if (!(level instanceof Error)) - dispatch({ type: "level", level }); - } catch { - return; - } - - setLoading(false); - })(); - return () => controller.abort(); - }, - [dispatch] - ); + useEffect(() => { + const controller = new AbortController(); + const signal = controller.signal; + (async () => { + setLoading(true); + + try { + let remoteLogging = await get( + "/remote_logging/enabled", + true, + 5000, + signal + ); + if (!(remoteLogging instanceof Error)) + dispatch({ type: "remoteLogging", remoteLogging }); + } catch { + return; + } + + try { + let level = await get("/remote_logging/level", true, 5000, signal); + if (!(level instanceof Error)) dispatch({ type: "level", level }); + } catch { + return; + } + + setLoading(false); + })(); + return () => controller.abort(); + }, [dispatch]); return [loading]; }; diff --git a/src/hooks/useWifiSettings.js b/src/hooks/useWifiSettings.js index fda40feb..e197f5c6 100644 --- a/src/hooks/useWifiSettings.js +++ b/src/hooks/useWifiSettings.js @@ -13,51 +13,53 @@ const useWifiSettings = () => { const [error, setError] = useState(null); const [loading, setLoading] = useState(true); - useEffect( - () => { - const controller = new AbortController(); - const signal = controller.signal; - (async () => { - try { - const wifiSettingsNoValidation = await get("/wifi_settings", true, 5000, signal); + useEffect(() => { + const controller = new AbortController(); + const signal = controller.signal; + (async () => { + try { + const wifiSettingsNoValidation = await get( + "/wifi_settings", + true, + 5000, + signal + ); - // this filters out the AltheaPhone network, which the user shouldn't edit - let wifiSettings = wifiSettingsNoValidation.filter(filterPhone); + // this filters out the AltheaPhone network, which the user shouldn't edit + let wifiSettings = wifiSettingsNoValidation.filter(filterPhone); - const channels = []; + const channels = []; - await Promise.all( - wifiSettings.map(async setting => { - let radio = setting.device.sectionName; - channels[radio] = []; - try { - channels[radio] = await get( - `/wifi_settings/get_channels/${radio}`, - true, - 5000, - signal - ); - } catch (e) { - if (e.message && e.message.includes("aborted")) return; - setError(true); - } - return channels[radio]; - }) - ); + await Promise.all( + wifiSettings.map(async setting => { + let radio = setting.device.sectionName; + channels[radio] = []; + try { + channels[radio] = await get( + `/wifi_settings/get_channels/${radio}`, + true, + 5000, + signal + ); + } catch (e) { + if (e.message && e.message.includes("aborted")) return; + setError(true); + } + return channels[radio]; + }) + ); - dispatch({ type: "channels", channels }); - dispatch({ type: "wifiSettings", wifiSettings }); - } catch (e) { - if (e.message && e.message.includes("aborted")) return; - setError(true); - } + dispatch({ type: "channels", channels }); + dispatch({ type: "wifiSettings", wifiSettings }); + } catch (e) { + if (e.message && e.message.includes("aborted")) return; + setError(true); + } - setLoading(false); - })(); - return () => controller.abort(); - }, - [dispatch] - ); + setLoading(false); + })(); + return () => controller.abort(); + }, [dispatch]); return [error, loading]; }; diff --git a/src/portOrderings.json b/src/portOrderings.json index c12ef2c6..a6b4cbb7 100644 --- a/src/portOrderings.json +++ b/src/portOrderings.json @@ -1,6 +1,6 @@ { "64": ["eth0", "eth1", "eth2", "eth3", "eth4"], - "cudy_wr2100": ["lan1","lan2","lan3","lan4","wan"], + "cudy_wr2100": ["lan1", "lan2", "lan3", "lan4", "wan"], "dir-860l-b1": ["eth0.1", "eth0.2", "eth0.3", "eth0.3", "eth0.5"], "erlite": ["eth0", "eth1", "eth2"], "ea3500": ["eth1", "eth0.3", "eth0.4", "eth0.5", "eth0.6"], @@ -8,11 +8,11 @@ "friendlyarm_nanopi-r2s": ["eth1", "eth0"], "gl-ar750": ["eth0", "eth1.1", "eth1.2"], "gl-b1300": ["eth0.3", "eth0.4", "eth1"], - "linksys_e5600": ["lan1","lan2","lan3","lan4","wan"], + "linksys_e5600": ["lan1", "lan2", "lan3", "lan4", "wan"], "linksys_ea6350v3": ["eth0.11", "eth0.12", "eth0.13", "eth0.14", "eth1"], - "linksys_ea7300v1": ["wan","lan1","lan2","lan3","lan4"], - "linksys_ea7300v2": ["wan","lan1","lan2","lan3","lan4"], - "linksys_ea7500v2": ["wan","lan1","lan2","lan3","lan4"], + "linksys_ea7300v1": ["wan", "lan1", "lan2", "lan3", "lan4"], + "linksys_ea7300v2": ["wan", "lan1", "lan2", "lan3", "lan4"], + "linksys_ea7500v2": ["wan", "lan1", "lan2", "lan3", "lan4"], "linksys_ex6100v2": ["eth0"], "linksys_mr8300": ["eth0.11", "eth0.12", "eth0.13", "eth0.14", "eth1"], "linksys_wrt3200acm": ["lan4", "lan3", "lan2", "lan1", "wan"], @@ -24,21 +24,28 @@ "linksys_wrt1900ac_v4": ["eth0.1", "eth0.3", "eth0.4", "eth0.5", "eth1.2"], "linksys_wrt1900acs_v4": ["eth0.1", "eth0.3", "eth0.4", "eth0.5", "eth1.2"], "mikrotik_hap-ac2": ["eth1", "eth0.14", "eth0.13", "eth0.12", "eth0.11"], - "mikrotik_routerboard-750gr3": ["wan","lan2","lan3","lan4","lan5"], - "mikrotik_routerboard-760igs": ["sfp", "wan","lan2","lan3","lan4","lan5"], + "mikrotik_routerboard-750gr3": ["wan", "lan2", "lan3", "lan4", "lan5"], + "mikrotik_routerboard-760igs": ["sfp", "wan", "lan2", "lan3", "lan4", "lan5"], "mynet-n600": ["eth0.1", "eth0.2", "eth0.3", "eth0.4", "eth1"], "mynet-n750": ["eth0.1", "eth0.4", "eth0.5", "eth0.3", "eth0.2"], "rpi-2": ["eth0"], "rpi-3": ["eth0"], "rpi-4": ["eth0"], "tl-wdr3600-v1": ["eth0.2", "eth0.3", "eth0.4", "eth0.5", "eth0.1"], - "tplink_archer-a6-v3": ["wan","lan1","lan2","lan3","lan4"], + "tplink_archer-a6-v3": ["wan", "lan1", "lan2", "lan3", "lan4"], "tplink_archer-c7-v2": ["eth0.1", "eth1.2", "eth1.3", "eth1.4", "eth1.5"], "turris-omnia": ["eth0.1", "eth0.2", "eth0.3", "eth0.3", "eth0.5"], "ubnt-erx": ["eth0", "eth1", "eth2", "eth3", "eth4"], "ubnt-erx-sfp": ["eth0", "eth1", "eth2", "eth3", "eth4", "eth5"], "ubnt-erx_v4": ["eth0.1", "eth0.2", "eth0.3", "eth0.4", "eth0.5"], - "ubnt-erx-sfp_v4": ["eth0.1", "eth0.2", "eth0.3", "eth0.4", "eth0.5", "eth0.6"], + "ubnt-erx-sfp_v4": [ + "eth0.1", + "eth0.2", + "eth0.3", + "eth0.4", + "eth0.5", + "eth0.6" + ], "ubnt-unifiac-lite": ["eth0"], "x86_64": ["eth0", "eth1", "eth2", "eth3", "eth4"], "zyxel_nbg6817": ["eth1.1", "eth1.2", "eth1.3", "eth1.4", "eth0.5"] diff --git a/src/store/actions.js b/src/store/actions.js index 288cfc6a..76dccc80 100644 --- a/src/store/actions.js +++ b/src/store/actions.js @@ -1,3 +1,4 @@ +/* eslint-disable import/no-anonymous-default-export */ import { BigNumber } from "bignumber.js"; import { toEth } from "utils"; diff --git a/src/store/fetch.js b/src/store/fetch.js index 8b1cd4c3..881623ca 100644 --- a/src/store/fetch.js +++ b/src/store/fetch.js @@ -72,18 +72,15 @@ export async function post(url, data, camel = true) { export function useDebounce(value, delay) { const [debouncedValue, setDebouncedValue] = useState(value); - useEffect( - () => { - const handler = setTimeout(() => { - setDebouncedValue(value); - }, delay); - - return () => { - clearTimeout(handler); - }; - }, - [delay, value] - ); + useEffect(() => { + const handler = setTimeout(() => { + setDebouncedValue(value); + }, delay); + + return () => { + clearTimeout(handler); + }; + }, [delay, value]); return debouncedValue; } diff --git a/src/store/index.js b/src/store/index.js index fd24ff9c..65ab4c9d 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -155,18 +155,15 @@ export async function post(url, data, camel = true) { export function useDebounce(value, delay) { const [debouncedValue, setDebouncedValue] = useState(value); - useEffect( - () => { - const handler = setTimeout(() => { - setDebouncedValue(value); - }, delay); - - return () => { - clearTimeout(handler); - }; - }, - [delay, value] - ); + useEffect(() => { + const handler = setTimeout(() => { + setDebouncedValue(value); + }, delay); + + return () => { + clearTimeout(handler); + }; + }, [delay, value]); return debouncedValue; } diff --git a/src/styles/althea.scss b/src/styles/althea.scss index 137a58a3..950b2cdf 100644 --- a/src/styles/althea.scss +++ b/src/styles/althea.scss @@ -1,12 +1,12 @@ -$primary: #3DADF5; -$secondary: #A8AEB3; +$primary: #3dadf5; +$secondary: #a8aeb3; $btn-border-radius: 4px; $btn-font-weight: bold; $input-btn-padding-y: 0.7rem; $input-btn-padding-x: 1.5rem; $font-size-base: 1.1rem; $spacer: 1.5rem; -$headings-margin-bottom: ($spacer / 1); +$headings-margin-bottom: ($spacer / 1); $input-placeholder-color: #aaa; @import "~bootstrap/scss/bootstrap"; @@ -14,30 +14,37 @@ $input-placeholder-color: #aaa; @import "./font"; .btn-secondary { - @include button-variant($secondary, darken($secondary, 7.5%), darken($secondary, 10%), lighten($secondary,5%), lighten($secondary, 10%), darken($secondary,30%)); + @include button-variant( + $secondary, + darken($secondary, 7.5%), + darken($secondary, 10%), + lighten($secondary, 5%), + lighten($secondary, 10%), + darken($secondary, 30%) + ); color: white; } body { - color: #002B36; + color: #002b36; font-family: Akkurat; -} +} label { margin-top: 15px; font-weight: bold; -} +} -.table-striped>thead>tr>th { +.table-striped > thead > tr > th { border-bottom: 1px solid #dadada; -} +} -.table-striped>tbody>tr { - >td { +.table-striped > tbody > tr { + > td { border: none; - } + } - &:nth-child(odd)>td { + &:nth-child(odd) > td { background-color: #f8f9fa; } } @@ -61,8 +68,8 @@ label { } .nav-item.active { - background: #ccc -} + background: #ccc; +} .dropdown-toggle::after { right: 0; @@ -77,7 +84,7 @@ label { width: 100%; top: 0px; left: 0px; -} +} #crosshair { position: absolute; @@ -88,7 +95,7 @@ label { top: 50%; left: 50%; margin: -100px 0 0 -100px; -} +} #controls { position: absolute; @@ -105,55 +112,55 @@ label { border-radius: 15px; z-index: 500; margin: 0 0 0 -150px; -} +} .nav-link { margin-top: 5px; margin-bottom: 15px; -} +} a.nav-link { color: #333; -} +} .nav-item.active { background: inherit !important; font-weight: bold; -} +} .navbar { - padding: 15px 10px; - background: #fff; - border: none; - border-radius: 0; - margin-bottom: 40px; - box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1); + padding: 15px 10px; + background: #fff; + border: none; + border-radius: 0; + margin-bottom: 40px; + box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1); } .navbar-brand { font-size: 24px; font-weight: bold; - color: #002B36 !important; + color: #002b36 !important; margin-left: 35px; -} +} .navbar-btn { - box-shadow: none; - outline: none !important; - border: none; + box-shadow: none; + outline: none !important; + border: none; } .line { - width: 100%; - height: 1px; - border-bottom: 1px dashed #ddd; - margin: 40px 0; + width: 100%; + height: 1px; + border-bottom: 1px dashed #ddd; + margin: 40px 0; } #sidebar { font-size: 1.2rem; width: 280px; - background: #F8F9FA; + background: #f8f9fa; color: #000; transition: all 0.3s; border-right: 1px solid #f0f0f0; @@ -161,11 +168,12 @@ a.nav-link { padding-left: 50px; } -#content, .modal-content { +#content, +.modal-content { font-size: 16px; p { color: gray; - } + } } #content { @@ -174,7 +182,7 @@ a.nav-link { transition: all 0.3s; text-align: left; max-width: 1000px; -} +} #content.active { width: 100%; @@ -183,41 +191,40 @@ a.nav-link { @media (min-width: 991px) { .card.card-small { flex: none; - width: calc(1/2 * 100% - (1 - 1/2) * 20px) !important; - } + width: calc(1 / 2 * 100% - (1 - 1 / 2) * 20px) !important; + } } @media (max-width: 991px) { #sidebar { - display: none; + display: none; } #content { margin-left: 0; padding: 30px 10px; - } + } .nav-link { margin-top: 5px; margin-bottom: 0; margin-left: 30px; - } + } .card { padding: 0 !important; - } + } } @include media-breakpoint-down(xs) { .card { padding: 0 !important; box-shadow: none !important; - border-top: 1px solid #efefef!important; + border-top: 1px solid #efefef !important; border-radius: 0 !important; margin: 0 !important; - } -} - + } +} .text-break { overflow-wrap: break-word; @@ -229,7 +236,7 @@ a.nav-link { .modal-header .close { opacity: 1; -} +} .modal-close { cursor: pointer; @@ -247,7 +254,7 @@ a.nav-link { width: calc(100% + 20px); margin: 10px -10px -20px -10px; background: #de5f4a; -} +} .input-group.is-invalid { ~ .invalid-feedback { @@ -268,14 +275,16 @@ a.nav-link { border-radius: 8px; } -input { +input { max-width: 100%; } -.custom-control-label::before, .custom-control-label::after { +.custom-control-label::before, +.custom-control-label::after { top: 0.2rem; -} +} -th, td { +th, +td { white-space: nowrap; -} +} diff --git a/src/styles/checkmark.css b/src/styles/checkmark.css index 37f1fb4a..8b2f4f14 100644 --- a/src/styles/checkmark.css +++ b/src/styles/checkmark.css @@ -37,7 +37,7 @@ /* When the checkbox is checked, add a blue background */ .container input:checked ~ .checkmark { - background-color: #2196F3; + background-color: #2196f3; } /* Create the checkmark/indicator (hidden when not checked) */ diff --git a/src/styles/font.scss b/src/styles/font.scss index 6a6d8120..5b7597b7 100755 --- a/src/styles/font.scss +++ b/src/styles/font.scss @@ -1,59 +1,65 @@ @font-face { - font-family: "Akkurat"; - src: url("../fonts_subsetted/lineto-akkurat-bold.eot"); - src: url("../fonts_subsetted/lineto-akkurat-bold.eot?#iefix") format("embedded-opentype"), - url("../fonts_subsetted/lineto-akkurat-bold.woff2") format("woff2"), - url("../fonts_subsetted/lineto-akkurat-bold.woff") format("woff"); - font-weight: bold; - font-style: normal; + font-family: "Akkurat"; + src: url("../fonts_subsetted/lineto-akkurat-bold.eot"); + src: url("../fonts_subsetted/lineto-akkurat-bold.eot?#iefix") + format("embedded-opentype"), + url("../fonts_subsetted/lineto-akkurat-bold.woff2") format("woff2"), + url("../fonts_subsetted/lineto-akkurat-bold.woff") format("woff"); + font-weight: bold; + font-style: normal; } @font-face { - font-family: "Akkurat"; - src: url("../fonts_subsetted/lineto-akkurat-bolditalic.eot"); - src: url("../fonts_subsetted/lineto-akkurat-bolditalic.eot?#iefix") format("embedded-opentype"), - url("../fonts_subsetted/lineto-akkurat-bolditalic.woff2") format("woff2"), - url("../fonts_subsetted/lineto-akkurat-bolditalic.woff") format("woff"); - font-weight: bold; - font-style: italic; + font-family: "Akkurat"; + src: url("../fonts_subsetted/lineto-akkurat-bolditalic.eot"); + src: url("../fonts_subsetted/lineto-akkurat-bolditalic.eot?#iefix") + format("embedded-opentype"), + url("../fonts_subsetted/lineto-akkurat-bolditalic.woff2") format("woff2"), + url("../fonts_subsetted/lineto-akkurat-bolditalic.woff") format("woff"); + font-weight: bold; + font-style: italic; } @font-face { - font-family: "Akkurat"; - src: url("../fonts_subsetted/lineto-akkurat-italic.eot"); - src: url("../fonts_subsetted/lineto-akkurat-italic.eot?#iefix") format("embedded-opentype"), - url("../fonts_subsetted/lineto-akkurat-italic.woff2") format("woff2"), - url("../fonts_subsetted/lineto-akkurat-italic.woff") format("woff"); - font-weight: normal; - font-style: italic; + font-family: "Akkurat"; + src: url("../fonts_subsetted/lineto-akkurat-italic.eot"); + src: url("../fonts_subsetted/lineto-akkurat-italic.eot?#iefix") + format("embedded-opentype"), + url("../fonts_subsetted/lineto-akkurat-italic.woff2") format("woff2"), + url("../fonts_subsetted/lineto-akkurat-italic.woff") format("woff"); + font-weight: normal; + font-style: italic; } @font-face { - font-family: "Akkurat"; - src: url("../fonts_subsetted/lineto-akkurat-light.eot"); - src: url("../fonts_subsetted/lineto-akkurat-light.eot?#iefix") format("embedded-opentype"), - url("../fonts_subsetted/lineto-akkurat-light.woff2") format("woff2"), - url("../fonts_subsetted/lineto-akkurat-light.woff") format("woff"); - font-weight: 200; - font-style: normal; + font-family: "Akkurat"; + src: url("../fonts_subsetted/lineto-akkurat-light.eot"); + src: url("../fonts_subsetted/lineto-akkurat-light.eot?#iefix") + format("embedded-opentype"), + url("../fonts_subsetted/lineto-akkurat-light.woff2") format("woff2"), + url("../fonts_subsetted/lineto-akkurat-light.woff") format("woff"); + font-weight: 200; + font-style: normal; } @font-face { - font-family: "Akkurat"; - src: url("../fonts_subsetted/lineto-akkurat-lightitalic.eot"); - src: url("../fonts_subsetted/lineto-akkurat-lightitalic.eot?#iefix") format("embedded-opentype"), - url("../fonts_subsetted/lineto-akkurat-lightitalic.woff2") format("woff2"), - url("../fonts_subsetted/lineto-akkurat-lightitalic.woff") format("woff"); - font-weight: lighter; - font-style: italic; + font-family: "Akkurat"; + src: url("../fonts_subsetted/lineto-akkurat-lightitalic.eot"); + src: url("../fonts_subsetted/lineto-akkurat-lightitalic.eot?#iefix") + format("embedded-opentype"), + url("../fonts_subsetted/lineto-akkurat-lightitalic.woff2") format("woff2"), + url("../fonts_subsetted/lineto-akkurat-lightitalic.woff") format("woff"); + font-weight: lighter; + font-style: italic; } @font-face { - font-family: "Akkurat"; - src: url("../fonts_subsetted/lineto-akkurat-regular.eot"); - src: url("../fonts_subsetted/lineto-akkurat-regular.eot?#iefix") format("embedded-opentype"), - url("../fonts_subsetted/lineto-akkurat-regular.woff2") format("woff2"), - url("../fonts_subsetted/lineto-akkurat-regular.woff") format("woff"); - font-weight: normal; - font-style: normal; + font-family: "Akkurat"; + src: url("../fonts_subsetted/lineto-akkurat-regular.eot"); + src: url("../fonts_subsetted/lineto-akkurat-regular.eot?#iefix") + format("embedded-opentype"), + url("../fonts_subsetted/lineto-akkurat-regular.woff2") format("woff2"), + url("../fonts_subsetted/lineto-akkurat-regular.woff") format("woff"); + font-weight: normal; + font-style: normal; } diff --git a/src/styles/react-bootstrap-switch.min.css b/src/styles/react-bootstrap-switch.min.css index 1c11ff43..28a6e46f 100644 --- a/src/styles/react-bootstrap-switch.min.css +++ b/src/styles/react-bootstrap-switch.min.css @@ -1,4 +1,3 @@ - /* ======================================================================== * react-bootstrap-switch - v15.5.3 * https://github.com/Julusian/react-bootstrap-switch @@ -9,4 +8,186 @@ * ======================================================================== */ -.bootstrap-switch{display:inline-block;direction:ltr;cursor:pointer;border-radius:4px;border:1px solid;border-color:#ccc;position:relative;text-align:left;overflow:hidden;line-height:8px;z-index:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle;-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.bootstrap-switch .bootstrap-switch-container{display:inline-block;top:0;border-radius:4px;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);vertical-align:middle}.bootstrap-switch .bootstrap-switch-handle-off,.bootstrap-switch .bootstrap-switch-handle-on,.bootstrap-switch .bootstrap-switch-label{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;cursor:pointer;display:table-cell;vertical-align:middle;padding:6px 12px;font-size:14px;line-height:20px}.bootstrap-switch .bootstrap-switch-handle-off,.bootstrap-switch .bootstrap-switch-handle-on{text-align:center;z-index:1}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-primary,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-primary{color:#fff;background:#337ab7}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-info,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-info{color:#fff;background:#5bc0de}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-success,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-success{color:#fff;background:#5cb85c}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-warning,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-warning{background:#f0ad4e;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-danger,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-danger{color:#fff;background:#d9534f}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-default,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-default{color:#000;background:#eee}.bootstrap-switch .bootstrap-switch-label{text-align:center;margin-top:-1px;margin-bottom:-1px;z-index:100;color:#333;background:#fff}.bootstrap-switch span::before{content:"\200b";white-space:nowrap}.bootstrap-switch .bootstrap-switch-handle-on{border-bottom-left-radius:3px;border-top-left-radius:3px}.bootstrap-switch .bootstrap-switch-handle-off{border-bottom-right-radius:3px;border-top-right-radius:3px}.bootstrap-switch input[type=checkbox],.bootstrap-switch input[type=radio]{position:absolute!important;top:0;left:0;margin:0;z-index:-1;opacity:0;visibility:hidden}.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-label{padding:1px 5px;font-size:12px;line-height:1.5}.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-label{padding:5px 10px;font-size:12px;line-height:1.5}.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-label{padding:6px 16px;font-size:18px;line-height:1.3333333}.bootstrap-switch.bootstrap-switch-disabled,.bootstrap-switch.bootstrap-switch-indeterminate,.bootstrap-switch.bootstrap-switch-readonly{cursor:default!important}.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-label,.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-label,.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-label{opacity:.5;cursor:default!important}.bootstrap-switch.bootstrap-switch-animate .bootstrap-switch-container{-webkit-transition:margin-left .5s;-o-transition:margin-left .5s;transition:margin-left .5s}.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-on{border-bottom-left-radius:0;border-top-left-radius:0;border-bottom-right-radius:3px;border-top-right-radius:3px}.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-off{border-bottom-right-radius:0;border-top-right-radius:0;border-bottom-left-radius:3px;border-top-left-radius:3px}.bootstrap-switch.bootstrap-switch-focused{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-off .bootstrap-switch-label,.bootstrap-switch.bootstrap-switch-on .bootstrap-switch-label{border-bottom-right-radius:3px;border-top-right-radius:3px}.bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-on .bootstrap-switch-label,.bootstrap-switch.bootstrap-switch-off .bootstrap-switch-label{border-bottom-left-radius:3px;border-top-left-radius:3px} \ No newline at end of file +.bootstrap-switch { + display: inline-block; + direction: ltr; + cursor: pointer; + border-radius: 4px; + border: 1px solid; + border-color: #ccc; + position: relative; + text-align: left; + overflow: hidden; + line-height: 8px; + z-index: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + vertical-align: middle; + -webkit-transition: border-color ease-in-out 0.15s, + box-shadow ease-in-out 0.15s; + -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; +} +.bootstrap-switch .bootstrap-switch-container { + display: inline-block; + top: 0; + border-radius: 4px; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + vertical-align: middle; +} +.bootstrap-switch .bootstrap-switch-handle-off, +.bootstrap-switch .bootstrap-switch-handle-on, +.bootstrap-switch .bootstrap-switch-label { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + cursor: pointer; + display: table-cell; + vertical-align: middle; + padding: 6px 12px; + font-size: 14px; + line-height: 20px; +} +.bootstrap-switch .bootstrap-switch-handle-off, +.bootstrap-switch .bootstrap-switch-handle-on { + text-align: center; + z-index: 1; +} +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-primary, +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-primary { + color: #fff; + background: #337ab7; +} +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-info, +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-info { + color: #fff; + background: #5bc0de; +} +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-success, +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-success { + color: #fff; + background: #5cb85c; +} +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-warning, +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-warning { + background: #f0ad4e; + color: #fff; +} +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-danger, +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-danger { + color: #fff; + background: #d9534f; +} +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-default, +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-default { + color: #000; + background: #eee; +} +.bootstrap-switch .bootstrap-switch-label { + text-align: center; + margin-top: -1px; + margin-bottom: -1px; + z-index: 100; + color: #333; + background: #fff; +} +.bootstrap-switch span::before { + content: "\200b"; + white-space: nowrap; +} +.bootstrap-switch .bootstrap-switch-handle-on { + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; +} +.bootstrap-switch .bootstrap-switch-handle-off { + border-bottom-right-radius: 3px; + border-top-right-radius: 3px; +} +.bootstrap-switch input[type="checkbox"], +.bootstrap-switch input[type="radio"] { + position: absolute !important; + top: 0; + left: 0; + margin: 0; + z-index: -1; + opacity: 0; + visibility: hidden; +} +.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-label { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; +} +.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-label { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; +} +.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-label { + padding: 6px 16px; + font-size: 18px; + line-height: 1.3333333; +} +.bootstrap-switch.bootstrap-switch-disabled, +.bootstrap-switch.bootstrap-switch-indeterminate, +.bootstrap-switch.bootstrap-switch-readonly { + cursor: default !important; +} +.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-label, +.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-label, +.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-label { + opacity: 0.5; + cursor: default !important; +} +.bootstrap-switch.bootstrap-switch-animate .bootstrap-switch-container { + -webkit-transition: margin-left 0.5s; + -o-transition: margin-left 0.5s; + transition: margin-left 0.5s; +} +.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-on { + border-bottom-left-radius: 0; + border-top-left-radius: 0; + border-bottom-right-radius: 3px; + border-top-right-radius: 3px; +} +.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-off { + border-bottom-right-radius: 0; + border-top-right-radius: 0; + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; +} +.bootstrap-switch.bootstrap-switch-focused { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), + 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), + 0 0 8px rgba(102, 175, 233, 0.6); +} +.bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-off + .bootstrap-switch-label, +.bootstrap-switch.bootstrap-switch-on .bootstrap-switch-label { + border-bottom-right-radius: 3px; + border-top-right-radius: 3px; +} +.bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-on + .bootstrap-switch-label, +.bootstrap-switch.bootstrap-switch-off .bootstrap-switch-label { + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; +} diff --git a/src/styles/react-phonenumber.scss b/src/styles/react-phonenumber.scss index b67e6989..789244be 100644 --- a/src/styles/react-phonenumber.scss +++ b/src/styles/react-phonenumber.scss @@ -1,160 +1,142 @@ -.react-phone-number-input__row -{ - /* This is done to stretch the contents of this component */ - display : flex; - align-items : center; +.react-phone-number-input__row { + /* This is done to stretch the contents of this component */ + display: flex; + align-items: center; } -.react-phone-number-input__phone -{ - /* The phone number input stretches to fill all empty space */ - flex : 1 1; +.react-phone-number-input__phone { + /* The phone number input stretches to fill all empty space */ + flex: 1 1; - /* The phone number input should shrink + /* The phone number input should shrink to make room for the extension input */ - min-width : 0; + min-width: 0; } -.react-phone-number-input__icon -{ - width : 2em; - box-sizing : content-box; +.react-phone-number-input__icon { + width: 2em; + box-sizing: content-box; } -.react-phone-number-input__error -{ - margin-left : calc(1.24em + 2px + 0.3em + 0.35em + 0.5em); - margin-top : calc(0.3rem); - color : #D30F00; +.react-phone-number-input__error { + margin-left: calc(1.24em + 2px + 0.3em + 0.35em + 0.5em); + margin-top: calc(0.3rem); + color: #d30f00; } /* Removes `` up/down arrows in Webkit browsers. */ .react-phone-number-input__ext-input::-webkit-inner-spin-button, -.react-phone-number-input__ext-input::-webkit-outer-spin-button -{ - margin : 0 !important; - -webkit-appearance : none !important; - -moz-appearance : textfield !important; +.react-phone-number-input__ext-input::-webkit-outer-spin-button { + margin: 0 !important; + -webkit-appearance: none !important; + -moz-appearance: textfield !important; } -.react-phone-number-input__ext-input -{ - width : 3em; +.react-phone-number-input__ext-input { + width: 3em; } -.react-phone-number-input__ext -{ - white-space: nowrap; +.react-phone-number-input__ext { + white-space: nowrap; } .react-phone-number-input__ext, -.react-phone-number-input__ext-input -{ - margin-left : 0.5em; +.react-phone-number-input__ext-input { + margin-left: 0.5em; } /* Styling native country `