From c3f680aa2220de4c878cf9d2a967c2a795ba4f64 Mon Sep 17 00:00:00 2001 From: louiscklaw Date: Sat, 7 Jun 2025 10:36:15 +0800 Subject: [PATCH] update demo-react-qr-code, --- .../CurrentWeather/WeatherProperty.tsx | 62 ++++++++++ .../components/CurrentWeather/index.tsx | 48 +++++++ .../DemoReactQrCode/components/CustomFab.jsx | 27 ++++ .../DemoReactQrCode/components/NoQRCodes.jsx | 15 +++ .../components/QRCodeScannedModal.jsx | 106 ++++++++++++++++ .../DemoReactQrCode/components/QRWebModal.jsx | 45 +++++++ .../components/SkeletonDashboard/index.tsx | 117 ++++++++++++++++++ .../src/pages/DemoReactQrCode/index.tsx | 30 ++--- .../src/pages/DemoReactQrCode/pages/Tab1.css | 0 .../src/pages/DemoReactQrCode/pages/Tab1.jsx | 114 +++++++++++++++++ .../src/pages/DemoReactQrCode/pages/Tab2.css | 0 .../src/pages/DemoReactQrCode/pages/Tab2.jsx | 105 ++++++++++++++++ .../src/pages/DemoReactQrCode/pages/Tab3.css | 0 .../src/pages/DemoReactQrCode/pages/Tab3.jsx | 102 +++++++++++++++ .../pages/DemoReactQrCode/sounds/close.wav | Bin 0 -> 33804 bytes .../src/pages/DemoReactQrCode/sounds/open.wav | Bin 0 -> 17072 bytes .../pages/DemoReactQrCode/store/QRStore.js | 19 +++ .../pages/DemoReactQrCode/store/Selectors.js | 6 + .../src/pages/DemoReactQrCode/store/index.js | 1 + .../DemoReactQrCode/theme/custom-tab-bar.scss | 30 +++++ .../pages/DemoReactQrCode/theme/variables.css | 77 ++++++++++++ 21 files changed, 885 insertions(+), 19 deletions(-) create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/components/CurrentWeather/WeatherProperty.tsx create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/components/CurrentWeather/index.tsx create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/components/CustomFab.jsx create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/components/NoQRCodes.jsx create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/components/QRCodeScannedModal.jsx create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/components/QRWebModal.jsx create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/components/SkeletonDashboard/index.tsx create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/pages/Tab1.css create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/pages/Tab1.jsx create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/pages/Tab2.css create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/pages/Tab2.jsx create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/pages/Tab3.css create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/pages/Tab3.jsx create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/sounds/close.wav create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/sounds/open.wav create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/store/QRStore.js create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/store/Selectors.js create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/store/index.js create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/theme/custom-tab-bar.scss create mode 100644 03_source/mobile/src/pages/DemoReactQrCode/theme/variables.css diff --git a/03_source/mobile/src/pages/DemoReactQrCode/components/CurrentWeather/WeatherProperty.tsx b/03_source/mobile/src/pages/DemoReactQrCode/components/CurrentWeather/WeatherProperty.tsx new file mode 100644 index 0000000..52949af --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactQrCode/components/CurrentWeather/WeatherProperty.tsx @@ -0,0 +1,62 @@ +import { IonCardSubtitle, IonCol, IonIcon, IonNote, IonRow } from '@ionic/react'; +import { pulseOutline, sunnyOutline, thermometerOutline } from 'ionicons/icons'; +import { useEffect, useState } from 'react'; + +export const WeatherProperty = ({ type, currentWeather }: { type: any; currentWeather: any }) => { + const [property, setProperty] = useState(false); + + const properties = { + wind: { + isIcon: false, + icon: '/assets/WeatherDemo/wind.png', + alt: 'wind', + label: 'Wind', + value: `${currentWeather.current.wind_mph}mph`, + }, + feelsLike: { + isIcon: true, + icon: thermometerOutline, + alt: 'feels like', + label: 'Feels like', + value: `${currentWeather.current.feelslike_c}°C`, + }, + indexUV: { + isIcon: true, + icon: sunnyOutline, + alt: 'index uv', + label: 'Index UV', + value: currentWeather.current.uv, + }, + pressure: { + isIcon: true, + icon: pulseOutline, + alt: 'pressure', + label: 'Pressure', + value: `${currentWeather.current.pressure_mb} mbar`, + }, + }; + + useEffect(() => { + setProperty(properties[type]); + }, [type]); + + return ( + + + + {!property.isIcon && ( + {property.alt} + )} + {property.isIcon && ( + + )} + + + + {property.label} + {property.value} + + + + ); +}; diff --git a/03_source/mobile/src/pages/DemoReactQrCode/components/CurrentWeather/index.tsx b/03_source/mobile/src/pages/DemoReactQrCode/components/CurrentWeather/index.tsx new file mode 100644 index 0000000..ceb4332 --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactQrCode/components/CurrentWeather/index.tsx @@ -0,0 +1,48 @@ +import { IonCard, IonCardContent, IonGrid, IonRow, IonText, IonCardTitle } from '@ionic/react'; +import { WeatherProperty } from './WeatherProperty'; + +export const CurrentWeather = ({ currentWeather }: { currentWeather: any }) => ( + + + + +

+ {currentWeather.location.region},{' '} + {currentWeather.location.country} +

+
+ +
+ condition + + +

{currentWeather.current.condition.text}

+
+ + +

{new Date(currentWeather.location.localtime).toDateString()}

+
+
+ + + {currentWeather.current.temp_c}℃ + + + + + + + + + + + + + +
+
+
+); diff --git a/03_source/mobile/src/pages/DemoReactQrCode/components/CustomFab.jsx b/03_source/mobile/src/pages/DemoReactQrCode/components/CustomFab.jsx new file mode 100644 index 0000000..2e19fe8 --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactQrCode/components/CustomFab.jsx @@ -0,0 +1,27 @@ +import { IonFab, IonFabButton, IonFabList, IonIcon } from '@ionic/react'; +import { addOutline, cameraOutline, qrCodeOutline } from 'ionicons/icons'; + +export const CustomFab = ({ start }) => { + return ( + + + + + + + + + + + + + + + + ); +}; diff --git a/03_source/mobile/src/pages/DemoReactQrCode/components/NoQRCodes.jsx b/03_source/mobile/src/pages/DemoReactQrCode/components/NoQRCodes.jsx new file mode 100644 index 0000000..08e6bd3 --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactQrCode/components/NoQRCodes.jsx @@ -0,0 +1,15 @@ +import { IonCol, IonRow, IonText } from '@ionic/react'; + +export const NoQRCodes = () => ( + + +

It looks like you don't have any QR codes stored.

+ icon + +

+ Click the button in the bottom right to scan a code or + generate a code. +

+
+
+); diff --git a/03_source/mobile/src/pages/DemoReactQrCode/components/QRCodeScannedModal.jsx b/03_source/mobile/src/pages/DemoReactQrCode/components/QRCodeScannedModal.jsx new file mode 100644 index 0000000..21f2c58 --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactQrCode/components/QRCodeScannedModal.jsx @@ -0,0 +1,106 @@ +import { + IonButton, + IonButtons, + IonCard, + IonCardContent, + IonCardHeader, + IonCardTitle, + IonCol, + IonContent, + IonGrid, + IonHeader, + IonIcon, + IonNote, + IonPage, + IonRow, + IonTitle, + IonToolbar, + useIonToast, +} from '@ionic/react'; +import QRCode from 'react-qr-code'; +import { addQRCode } from '../store/QRStore'; + +import useSound from 'use-sound'; +import closeSound from '../sounds/close.wav'; +import { reloadOutline } from 'ionicons/icons'; + +export const QRCodeScannedModal = ({ dismiss, code, set, scan }) => { + const [play] = useSound(closeSound); + const [showToast] = useIonToast(); + + const handleDismiss = () => { + dismiss(); + play(); + }; + + const handleScanAgain = () => { + handleDismiss(); + + setTimeout(() => { + scan(); + }, 10); + }; + + const handleAdd = async () => { + addQRCode(code.text ? code.text : code, true); + showToast({ + header: 'Success!', + message: 'QR Code stored successfully.', + duration: 3000, + color: 'primary', + }); + + handleDismiss(); + }; + + return ( + + + + View QR Code + + Close + + + + + + + + + + + + + + + + + QR Code data + This is what the code represents + + +

{code.text ? code.text : code}

+
+
+
+
+ + + + + +   Scan again + + + + + Store → + + + +
+
+
+ ); +}; diff --git a/03_source/mobile/src/pages/DemoReactQrCode/components/QRWebModal.jsx b/03_source/mobile/src/pages/DemoReactQrCode/components/QRWebModal.jsx new file mode 100644 index 0000000..8d1775d --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactQrCode/components/QRWebModal.jsx @@ -0,0 +1,45 @@ +import { + IonButton, + IonButtons, + IonCol, + IonContent, + IonGrid, + IonHeader, + IonPage, + IonRow, + IonTitle, + IonToolbar, +} from '@ionic/react'; +// import QrReader from "react-qr-reader"; + +export const QRWebModal = ({ dismiss, set, scan, error }) => { + return ( + + + + Scan QR Code + + Close + + + + + + + + + {/* + + */} + + + + + + ); +}; diff --git a/03_source/mobile/src/pages/DemoReactQrCode/components/SkeletonDashboard/index.tsx b/03_source/mobile/src/pages/DemoReactQrCode/components/SkeletonDashboard/index.tsx new file mode 100644 index 0000000..234fb9b --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactQrCode/components/SkeletonDashboard/index.tsx @@ -0,0 +1,117 @@ +import { + IonCard, + IonCardContent, + IonCardSubtitle, + IonCardTitle, + IonCol, + IonGrid, + IonIcon, + IonNote, + IonRow, + IonSkeletonText, + IonText, + IonThumbnail, +} from '@ionic/react'; +import { pulseOutline, sunnyOutline, thermometerOutline } from 'ionicons/icons'; + +export const SkeletonDashboard = () => ( + + + + +

+ +

+
+ +
+ + + + + +

+ +

+
+ + +

+ +

+
+
+ + + + + + + + + + + wind + + + + Wind + + + + + + + + + + + + + + + Feels like + + + + + + + + + + + + + + + + + Index UV + + + + + + + + + + + + + + + Pressure + + + + + + + + +
+
+
+); diff --git a/03_source/mobile/src/pages/DemoReactQrCode/index.tsx b/03_source/mobile/src/pages/DemoReactQrCode/index.tsx index 7c0fd59..70fef09 100644 --- a/03_source/mobile/src/pages/DemoReactQrCode/index.tsx +++ b/03_source/mobile/src/pages/DemoReactQrCode/index.tsx @@ -3,38 +3,30 @@ import { IonIcon, IonLabel, IonRouterOutlet, IonTabBar, IonTabButton, IonTabs } import { cloudOutline, searchOutline } from 'ionicons/icons'; import { Route, Redirect } from 'react-router'; -import Tab1 from './AppPages/Tab1'; -import Tab2 from './AppPages/Tab2'; +// import Tab1 from './AppPages/Tab1'; +// import Tab2 from './AppPages/Tab2'; import './style.scss'; -function DemoReactQrCode() { +function DemoWeatherAppUi() { return ( - + - + - - + + + - {/* */} - - - - Dashboard - - - - Search - - + + ); } -export default DemoReactQrCode; +export default DemoWeatherAppUi; diff --git a/03_source/mobile/src/pages/DemoReactQrCode/pages/Tab1.css b/03_source/mobile/src/pages/DemoReactQrCode/pages/Tab1.css new file mode 100644 index 0000000..e69de29 diff --git a/03_source/mobile/src/pages/DemoReactQrCode/pages/Tab1.jsx b/03_source/mobile/src/pages/DemoReactQrCode/pages/Tab1.jsx new file mode 100644 index 0000000..ecec4dc --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactQrCode/pages/Tab1.jsx @@ -0,0 +1,114 @@ +import { BarcodeScanner } from '@ionic-native/barcode-scanner'; +import { IonContent, IonGrid, IonHeader, IonPage, IonTitle, IonToolbar, useIonModal, getPlatforms } from '@ionic/react'; +import { useStoreState } from 'pullstate'; +import { useState } from 'react'; +import { useRef } from 'react'; +import useSound from 'use-sound'; +import { CustomFab } from '../components/CustomFab'; +import { NoQRCodes } from '../components/NoQRCodes'; +import { QRCodeList } from '../components/QRCodeList'; +import { QRCodeScannedModal } from '../components/QRCodeScannedModal'; +import { QRStore } from '../store'; +import { getCodes } from '../store/Selectors'; +import './Tab1.css'; + +import openSound from "../sounds/open.wav"; +import { QRWebModal } from '../components/QRWebModal'; + +const Tab1 = () => { + + const pageRef = useRef(); + const codes = useStoreState(QRStore, getCodes); + const [ play ] = useSound(openSound); + + const [ QRData, setQRData ] = useState(false); + + const handleScan = data => { + + if (data) { + + setQRData(data); + play(); + handleSuccess(data); + } + } + + const handleError = err => { + + console.error(err) + } + + const start = async () => { + + const platforms = getPlatforms(); + const isWeb = (platforms.includes("desktop") || platforms.includes("mobileweb") || platforms.includes("pwa")); + + if (!isWeb) { + + const data = await BarcodeScanner.scan(); + + if (data) { + handleSuccess(data); + } + } else { + + presentWebModal({ + + presentingElement: pageRef.current + }); + } + } + + const handleSuccess = data => { + + setQRData(data); + console.log(data); + dismissWebModal(); + + play(); + present({ + + presentingElement: pageRef.current + }); + } + + const [ present, dismiss ] = useIonModal(QRCodeScannedModal, { + + dismiss: () => dismiss(), + code: QRData, + set: () => setQRData(), + scan: () => start() + }); + + const [ presentWebModal, dismissWebModal ] = useIonModal(QRWebModal, { + + dismiss: () => dismissWebModal(), + set: () => setQRData(), + scan: handleScan, + error: handleError + }); + + return ( + + + + QR Codes + + + + + + QR Codes + + + + { codes.length < 1 && } + { codes.length > 0 && } + + + + + ); +}; + +export default Tab1; diff --git a/03_source/mobile/src/pages/DemoReactQrCode/pages/Tab2.css b/03_source/mobile/src/pages/DemoReactQrCode/pages/Tab2.css new file mode 100644 index 0000000..e69de29 diff --git a/03_source/mobile/src/pages/DemoReactQrCode/pages/Tab2.jsx b/03_source/mobile/src/pages/DemoReactQrCode/pages/Tab2.jsx new file mode 100644 index 0000000..ea65fcf --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactQrCode/pages/Tab2.jsx @@ -0,0 +1,105 @@ +import { IonBackButton, IonButton, IonButtons, IonCol, IonContent, IonGrid, IonHeader, IonInput, IonItem, IonLabel, IonNote, IonPage, IonRow, IonTextarea, IonTitle, IonToolbar, useIonToast } from '@ionic/react'; +import './Tab2.css'; + +import QRCode from "react-qr-code"; +import { useState } from 'react'; +import { addQRCode } from '../store/QRStore'; + +const Tab2 = () => { + + const [ data, setData ] = useState(""); + const [ showToast ] = useIonToast(); + + const handleAdd = async () => { + + if (data === "") { + + showToast({ + + header: "Error!", + message: "Please enter some data to store.", + duration: 3000, + color: "danger" + }); + } else { + + addQRCode(data); + showToast({ + + header: "Success!", + message: "QR Code stored successfully.", + duration: 3000, + color: "primary" + }); + + setData(""); + } + } + + return ( + + + + + + + Generate QR Code + + + + + + Generate QR Code + + + + + + + + + +

You can generate a QR code to store or share with friends.

+

You'll see a live preview of the QR Code

+
+
+
+
+ + + + + Data to store + setData(e.target.value) } /> + + + + + + + { data !== "" ? : placeholder qr } + + + + + + + +

When you're ready, you can store the generated QR Code

+
+
+
+
+ + + + Store → + + +
+
+
+ ); +}; + +export default Tab2; diff --git a/03_source/mobile/src/pages/DemoReactQrCode/pages/Tab3.css b/03_source/mobile/src/pages/DemoReactQrCode/pages/Tab3.css new file mode 100644 index 0000000..e69de29 diff --git a/03_source/mobile/src/pages/DemoReactQrCode/pages/Tab3.jsx b/03_source/mobile/src/pages/DemoReactQrCode/pages/Tab3.jsx new file mode 100644 index 0000000..42c2ba6 --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactQrCode/pages/Tab3.jsx @@ -0,0 +1,102 @@ +import { IonBackButton, IonButton, IonButtons, IonCard, IonCardContent, IonCardHeader, IonCardTitle, IonCol, IonContent, IonGrid, IonHeader, IonIcon, IonNote, IonPage, IonRow, IonTitle, IonToolbar, useIonToast } from '@ionic/react'; +import './Tab3.css'; +import { useState } from 'react'; + +import { BarcodeScanner } from "@ionic-native/barcode-scanner"; +import QRCode from 'react-qr-code'; +import { addQRCode } from '../store/QRStore'; +import { reloadOutline } from 'ionicons/icons'; + +const Tab3 = () => { + + const [ QRData, setQRData ] = useState(false); + + const start = async () => { + + const data = await BarcodeScanner.scan(); + setQRData(data); + } + + const [ showToast ] = useIonToast(); + + const handleAdd = async () => { + + addQRCode(QRData.text, true); + showToast({ + + header: "Success!", + message: "QR Code stored successfully.", + duration: 3000, + color: "primary" + }); + + setQRData(false); + } + + return ( + + + + + + + Scan QR Code + + + + + + Scan QR Code + + + + + { !QRData && + + + Scan → + + + } + + { QRData && + <> + + + + + + + + + + + QR Code data + This is what the code represents + + +

{ QRData.text }

+
+
+
+
+ + + + +   + Scan again + + + Store → + + + + } +
+
+
+ ); +}; + +export default Tab3; diff --git a/03_source/mobile/src/pages/DemoReactQrCode/sounds/close.wav b/03_source/mobile/src/pages/DemoReactQrCode/sounds/close.wav new file mode 100644 index 0000000000000000000000000000000000000000..7ca4e4e9c73e74c8e9f8c27ad21de46a5f81d474 GIT binary patch literal 33804 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 literal 0 HcmV?d00001 diff --git a/03_source/mobile/src/pages/DemoReactQrCode/sounds/open.wav b/03_source/mobile/src/pages/DemoReactQrCode/sounds/open.wav new file mode 100644 index 0000000000000000000000000000000000000000..78c825484f3f6663233e8ad2874e2672ecf2605f GIT binary patch literal 17072 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 XWV|z)(*tV10(7xRXKP~VYRdlsY%oDo literal 0 HcmV?d00001 diff --git a/03_source/mobile/src/pages/DemoReactQrCode/store/QRStore.js b/03_source/mobile/src/pages/DemoReactQrCode/store/QRStore.js new file mode 100644 index 0000000..2878652 --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactQrCode/store/QRStore.js @@ -0,0 +1,19 @@ +import { Store } from 'pullstate'; + +const QRStore = new Store({ + codes: [], +}); + +export default QRStore; + +export const addQRCode = (data, scanned = false) => { + QRStore.update((s) => { + s.codes = [...s.codes, { id: new Date(), data, scanned }]; + }); +}; + +export const removeQRCode = (id) => { + QRStore.update((s) => { + s.codes = s.codes.filter((code) => code.id !== id); + }); +}; diff --git a/03_source/mobile/src/pages/DemoReactQrCode/store/Selectors.js b/03_source/mobile/src/pages/DemoReactQrCode/store/Selectors.js new file mode 100644 index 0000000..d74c840 --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactQrCode/store/Selectors.js @@ -0,0 +1,6 @@ +import { createSelector } from 'reselect'; + +const getState = (state) => state; + +// General getters +export const getCodes = createSelector(getState, (state) => state.codes); diff --git a/03_source/mobile/src/pages/DemoReactQrCode/store/index.js b/03_source/mobile/src/pages/DemoReactQrCode/store/index.js new file mode 100644 index 0000000..18573c9 --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactQrCode/store/index.js @@ -0,0 +1 @@ +export { default as QRStore } from './QRStore'; diff --git a/03_source/mobile/src/pages/DemoReactQrCode/theme/custom-tab-bar.scss b/03_source/mobile/src/pages/DemoReactQrCode/theme/custom-tab-bar.scss new file mode 100644 index 0000000..02ee8c1 --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactQrCode/theme/custom-tab-bar.scss @@ -0,0 +1,30 @@ +:root { + + /* --ion-background-color: white; */ + --ion-tab-bar-color: rgb(76, 112, 141); + --ion-tab-bar-color-selected: white; +} + +ion-tab-bar { + + --background: rgb(1, 72, 131); + box-shadow: 0px 1px 8px rgba(0, 0, 0, 0.4); + border-radius: 50px !important; + + height: 50px; + width: 40%; + padding-top: 5px; + padding-bottom: 5px; + padding-left: 10px; + padding-right: 10px; + + bottom: 24px; + position: relative; + margin: 0 auto !important; + border-top: none; +} + +ion-tab-button { + + border-radius: 16px !important; +} diff --git a/03_source/mobile/src/pages/DemoReactQrCode/theme/variables.css b/03_source/mobile/src/pages/DemoReactQrCode/theme/variables.css new file mode 100644 index 0000000..088e83c --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactQrCode/theme/variables.css @@ -0,0 +1,77 @@ +/* Ionic Variables and Theming. For more info, please see: +http://ionicframework.com/docs/theming/ */ + +/** Ionic CSS Variables **/ +:root { + /** primary **/ + --ion-color-primary: #3880ff; + --ion-color-primary-rgb: 56, 128, 255; + --ion-color-primary-contrast: #ffffff; + --ion-color-primary-contrast-rgb: 255, 255, 255; + --ion-color-primary-shade: #3171e0; + --ion-color-primary-tint: #4c8dff; + + /** secondary **/ + --ion-color-secondary: #3dc2ff; + --ion-color-secondary-rgb: 61, 194, 255; + --ion-color-secondary-contrast: #ffffff; + --ion-color-secondary-contrast-rgb: 255, 255, 255; + --ion-color-secondary-shade: #36abe0; + --ion-color-secondary-tint: #50c8ff; + + /** tertiary **/ + --ion-color-tertiary: #5260ff; + --ion-color-tertiary-rgb: 82, 96, 255; + --ion-color-tertiary-contrast: #ffffff; + --ion-color-tertiary-contrast-rgb: 255, 255, 255; + --ion-color-tertiary-shade: #4854e0; + --ion-color-tertiary-tint: #6370ff; + + /** success **/ + --ion-color-success: #2dd36f; + --ion-color-success-rgb: 45, 211, 111; + --ion-color-success-contrast: #ffffff; + --ion-color-success-contrast-rgb: 255, 255, 255; + --ion-color-success-shade: #28ba62; + --ion-color-success-tint: #42d77d; + + /** warning **/ + --ion-color-warning: #ffc409; + --ion-color-warning-rgb: 255, 196, 9; + --ion-color-warning-contrast: #000000; + --ion-color-warning-contrast-rgb: 0, 0, 0; + --ion-color-warning-shade: #e0ac08; + --ion-color-warning-tint: #ffca22; + + /** danger **/ + --ion-color-danger: #eb445a; + --ion-color-danger-rgb: 235, 68, 90; + --ion-color-danger-contrast: #ffffff; + --ion-color-danger-contrast-rgb: 255, 255, 255; + --ion-color-danger-shade: #cf3c4f; + --ion-color-danger-tint: #ed576b; + + /** dark **/ + --ion-color-dark: #222428; + --ion-color-dark-rgb: 34, 36, 40; + --ion-color-dark-contrast: #ffffff; + --ion-color-dark-contrast-rgb: 255, 255, 255; + --ion-color-dark-shade: #1e2023; + --ion-color-dark-tint: #383a3e; + + /** medium **/ + --ion-color-medium: #92949c; + --ion-color-medium-rgb: 146, 148, 156; + --ion-color-medium-contrast: #ffffff; + --ion-color-medium-contrast-rgb: 255, 255, 255; + --ion-color-medium-shade: #808289; + --ion-color-medium-tint: #9d9fa6; + + /** light **/ + --ion-color-light: #f4f5f8; + --ion-color-light-rgb: 244, 245, 248; + --ion-color-light-contrast: #000000; + --ion-color-light-contrast-rgb: 0, 0, 0; + --ion-color-light-shade: #d7d8da; + --ion-color-light-tint: #f5f6f9; +} \ No newline at end of file