From 47093d62996c86f8e268a0e27027b6a080aa2a94 Mon Sep 17 00:00:00 2001 From: Abdulrhmn Ghanem Date: Sat, 5 Oct 2024 04:03:08 +0300 Subject: [PATCH 1/7] Convert `BuyParts` Component to typescript --- .../Board/BuyParts/{Bom.jsx => Bom.tsx} | 21 ++-- .../{DirectStores.jsx => DirectStores.tsx} | 9 +- .../Board/BuyParts/InstallPrompt.jsx | 105 ----------------- .../Board/BuyParts/InstallPrompt.module.scss | 14 --- .../Board/BuyParts/index.module.scss | 1 + .../Board/BuyParts/{index.jsx => index.tsx} | 111 ++++-------------- frontend/src/index.d.ts | 10 ++ frontend/test/BuyParts.test.tsx | 10 ++ 8 files changed, 59 insertions(+), 222 deletions(-) rename frontend/src/components/Board/BuyParts/{Bom.jsx => Bom.tsx} (82%) rename frontend/src/components/Board/BuyParts/{DirectStores.jsx => DirectStores.tsx} (95%) delete mode 100644 frontend/src/components/Board/BuyParts/InstallPrompt.jsx delete mode 100644 frontend/src/components/Board/BuyParts/InstallPrompt.module.scss rename frontend/src/components/Board/BuyParts/{index.jsx => index.tsx} (70%) create mode 100644 frontend/src/index.d.ts diff --git a/frontend/src/components/Board/BuyParts/Bom.jsx b/frontend/src/components/Board/BuyParts/Bom.tsx similarity index 82% rename from frontend/src/components/Board/BuyParts/Bom.jsx rename to frontend/src/components/Board/BuyParts/Bom.tsx index 955942b56f..58298e0446 100644 --- a/frontend/src/components/Board/BuyParts/Bom.jsx +++ b/frontend/src/components/Board/BuyParts/Bom.tsx @@ -2,11 +2,10 @@ import React, { useEffect, useState } from 'react' import { Icon, Table } from 'semantic-ui-react' import DoubleScrollBar from 'react-double-scrollbar' -import { array, bool, func, number, string } from 'prop-types' import styles from './Bom.module.scss' import TsvTable from './TsvTable' -const Bom = ({ length, parts, tsv }) => { +const Bom = ({ length, parts, tsv }: BomProps) => { const [diff, setDiff] = useState(0) const [collapsed, setCollapsed] = useState(true) @@ -32,7 +31,7 @@ const Bom = ({ length, parts, tsv }) => { ) } -const ExpandBom = ({ diff, collapsed, setCollapsed }) => { +const ExpandBom = ({ diff, collapsed, setCollapsed }: ExpandBomProps) => { const summary = diff > 0 && collapsed ? ( @@ -71,16 +70,16 @@ const ExpandBom = ({ diff, collapsed, setCollapsed }) => { ) } -Bom.propTypes = { - length: number.isRequired, - parts: array.isRequired, - tsv: string.isRequired, +interface BomProps { + length: number + parts: Array + tsv: string } -ExpandBom.propTypes = { - diff: number.isRequired, - collapsed: bool.isRequired, - setCollapsed: func.isRequired, +interface ExpandBomProps { + diff: number + collapsed: boolean + setCollapsed: (collapsed: boolean) => void } export default Bom diff --git a/frontend/src/components/Board/BuyParts/DirectStores.jsx b/frontend/src/components/Board/BuyParts/DirectStores.tsx similarity index 95% rename from frontend/src/components/Board/BuyParts/DirectStores.jsx rename to frontend/src/components/Board/BuyParts/DirectStores.tsx index bc3fde2579..e8e5791073 100644 --- a/frontend/src/components/Board/BuyParts/DirectStores.jsx +++ b/frontend/src/components/Board/BuyParts/DirectStores.tsx @@ -1,11 +1,10 @@ import React, { useEffect, useState, useCallback } from 'react' -import { array, number } from 'prop-types' import DigikeyData from '1-click-bom-minimal/lib/data/digikey.json' import FarnellData from '1-click-bom-minimal/lib/data/farnell.json' import countriesData from '1-click-bom-minimal/lib/data/countries.json' -const DirectStores = ({ items, multiplier }) => { +const DirectStores = ({ items, multiplier }: DirectStoresProps) => { const [countryCode, setCountryCode] = useState('Other') const [digikeyParts, setDigikeyParts] = useState([]) const [farnellParts, setFarnellParts] = useState([]) @@ -132,8 +131,8 @@ const DirectStores = ({ items, multiplier }) => { ) } -DirectStores.propTypes = { - items: array.isRequired, - multiplier: number.isRequired, +interface DirectStoresProps { + items: Array + multiplier: number } export default DirectStores diff --git a/frontend/src/components/Board/BuyParts/InstallPrompt.jsx b/frontend/src/components/Board/BuyParts/InstallPrompt.jsx deleted file mode 100644 index 13546be102..0000000000 --- a/frontend/src/components/Board/BuyParts/InstallPrompt.jsx +++ /dev/null @@ -1,105 +0,0 @@ -import React, { useEffect, useState } from 'react' -import Link from 'next/link' - -import { Icon, Message } from 'semantic-ui-react' -import { func, string } from 'prop-types' - -import BrowserVersion from '@utils/getBrowserVersion' -import styles from './InstallPrompt.module.scss' - -export const install1ClickBOM = () => { - const version = BrowserVersion() - let onClick - if (/Chrome/.test(version)) { - onClick = () => { - window.plausible('Install Extension') - window.open( - 'https://chrome.google.com/webstore/detail/kitspace-1-click-bom/mflpmlediakefinapghmabapjeippfdi', - ) - } - } else if (/Firefox/.test(version)) { - onClick = () => { - window.plausible('Install Extension') - window.open('https://addons.mozilla.org/en-US/firefox/addon/1clickbom') - } - } else { - onClick = () => { - window.plausible('Install Extension') - window.open('/1-click-bom', '_self') - } - } - return onClick() -} - -const InstallPrompt = ({ extensionPresence }) => { - const [isCompatible, setIsCompatible] = useState(true) - const [timedOut, setTimedOut] = useState(false) - - const getCompatibility = () => { - if (typeof navigator === 'undefined') { - return true - } - if (/Mobile/i.test(navigator.userAgent)) { - return false - } - const version = BrowserVersion() - return /Chrome/.test(version) || /Firefox/.test(version) - } - - useEffect(() => { - setTimedOut(() => { - setTimedOut(true) - setIsCompatible(getCompatibility()) - }, 5000) - }, []) - - if (extensionPresence === 'present') { - return
- } - if (timedOut) { - return isCompatible ? ( - - ) : ( - - ) - } - return null -} - -const PleaseInstall = ({ install1ClickBOMCallback }) => ( - - - Please{' '} - {' '} - make full use of this feature. - -) - -const NotCompatible = () => ( - - - Sorry, the{' '} - - 1-click BOM extension - {' '} - is not yet available for your browser. Only the Digikey add-to-cart links work - fully, Farnell and Newark should work but the references will not be added as - line-notes. - -) - -InstallPrompt.propTypes = { - extensionPresence: string.isRequired, -} - -PleaseInstall.propTypes = { - install1ClickBOMCallback: func.isRequired, -} - -export default InstallPrompt diff --git a/frontend/src/components/Board/BuyParts/InstallPrompt.module.scss b/frontend/src/components/Board/BuyParts/InstallPrompt.module.scss deleted file mode 100644 index 7345ea0159..0000000000 --- a/frontend/src/components/Board/BuyParts/InstallPrompt.module.scss +++ /dev/null @@ -1,14 +0,0 @@ -@import '../../colors.scss'; - -.extensionLinkButton { - background: none!important; - border: none; - padding: 0!important; - color:$mine-shaft; - font-weight: bold; - cursor: pointer; -} - -.extensionLinkButton:hover { - text-decoration: underline; -} \ No newline at end of file diff --git a/frontend/src/components/Board/BuyParts/index.module.scss b/frontend/src/components/Board/BuyParts/index.module.scss index d62ee2a050..1e4856d321 100644 --- a/frontend/src/components/Board/BuyParts/index.module.scss +++ b/frontend/src/components/Board/BuyParts/index.module.scss @@ -1,6 +1,7 @@ @import '../../breakpoint.scss'; .notSelectable { + -webkit-user-select: none; user-select: none; cursor: default; } diff --git a/frontend/src/components/Board/BuyParts/index.jsx b/frontend/src/components/Board/BuyParts/index.tsx similarity index 70% rename from frontend/src/components/Board/BuyParts/index.jsx rename to frontend/src/components/Board/BuyParts/index.tsx index 1ddcbab8cf..f5842bbebe 100644 --- a/frontend/src/components/Board/BuyParts/index.jsx +++ b/frontend/src/components/Board/BuyParts/index.tsx @@ -1,19 +1,15 @@ import React, { useEffect, useState } from 'react' -import { array, bool, func, number, string } from 'prop-types' import OneClickBom from '1-click-bom-minimal' import { Header, Icon, Segment, Input, Button } from 'semantic-ui-react' import Bom from './Bom' -import InstallPrompt, { install1ClickBOM } from './InstallPrompt' import DirectStores from './DirectStores' import styles from './index.module.scss' -const BuyParts = ({ projectFullName, lines, parts }) => { - const [extensionPresence, setExtensionPresence] = useState('unknown') +const BuyParts = ({ projectFullName, lines, parts }: BuyPartsProps) => { const [buyMultiplier, setBuyMultiplier] = useState(1) const [mult, setMult] = useState(1) const [buyAddPercent, setBuyAddPercent] = useState(0) - const [adding, setAdding] = useState({}) const buyParts = distributor => { window.plausible('Buy Parts', { @@ -23,17 +19,6 @@ const BuyParts = ({ projectFullName, lines, parts }) => { multiplier: mult, }, }) - window.postMessage( - { - from: 'page', - message: 'quickAddToCart', - value: { - retailer: distributor, - multiplier: mult, - }, - }, - '*', - ) } const retailerList = OneClickBom.getRetailers() @@ -52,10 +37,7 @@ const BuyParts = ({ projectFullName, lines, parts }) => { return ( buyParts(name)} - extensionPresence={name === 'Digikey' ? 'absent' : extensionPresence} - install1ClickBOM={install1ClickBOM} name={name} numberOfLines={numberOfLines} numberOfParts={numberOfParts} @@ -67,29 +49,6 @@ const BuyParts = ({ projectFullName, lines, parts }) => { }) .filter(l => l != null) - useEffect(() => { - // extension communication - window.addEventListener( - 'message', - event => { - if (event.source !== window) { - return - } - if (event.data.from === 'extension') { - setExtensionPresence('present') - switch (event.data.message) { - case 'updateAddingState': - setAdding(event.data.value) - break - default: - break - } - } - }, - false, - ) - }, []) - useEffect(() => { const multi = buyMultiplier if (Number.isNaN(multi) || multi < 1) { @@ -110,6 +69,7 @@ const BuyParts = ({ projectFullName, lines, parts }) => { return OneClickBom.writeTSV(linesMult) } const hasPurchasableParts = retailerButtons.length !== 0 + return (
@@ -118,7 +78,6 @@ const BuyParts = ({ projectFullName, lines, parts }) => {
{hasPurchasableParts ? ( <> - ( +}: AdjustQuantityProps) => ( Adjust quantity: @@ -207,26 +166,11 @@ const AdjustQuantity = ({ const RetailerButton = ({ name, buyParts, - install1ClickBOM, - extensionPresence, numberOfLines, totalLines, numberOfParts, - adding, -}) => { - let onClick = buyParts - // if the extension is not here fallback to direct submissions - if (extensionPresence !== 'present' && typeof document !== 'undefined') { - onClick = () => { - const form = document.getElementById(`${name}Form`) - if (form) { - form.submit() - } else { - install1ClickBOM() - } - } - } - const color = numberOfLines === totalLines ? 'green' : 'pink' +}: RetailerButtonProps) => { + const color = 'green' return (