diff --git a/03_source/mobile/src/pages/DemoAccordionTutorial/AppPages/Tab1.jsx b/03_source/mobile/src/pages/DemoAccordionTutorial/AppPages/Tab1.jsx new file mode 100644 index 0000000..54ab2b9 --- /dev/null +++ b/03_source/mobile/src/pages/DemoAccordionTutorial/AppPages/Tab1.jsx @@ -0,0 +1,96 @@ +import { + IonButton, + IonButtons, + IonCol, + IonContent, + IonHeader, + IonIcon, + IonPage, + IonRow, + IonTitle, + IonToolbar, + useIonRouter, +} from '@ionic/react'; + +import { Geolocation } from '@capacitor/geolocation'; +import { useEffect, useState } from 'react'; +import { SkeletonDashboard } from '../components/SkeletonDashboard'; +import { chevronBackOutline, refreshOutline } from 'ionicons/icons'; +import { CurrentWeather } from '../components/CurrentWeather'; + +function Tab1() { + const router = useIonRouter(); + + const [currentWeather, setCurrentWeather] = useState(false); + + useEffect(() => { + getCurrentPosition(); + }, []); + + const getCurrentPosition = async () => { + setCurrentWeather(false); + const coordinates = await Geolocation.getCurrentPosition(); + getAddress(coordinates.coords); + }; + + const getAddress = async (coords) => { + const query = `${coords.latitude},${coords.longitude}`; + const response = await fetch( + `https://api.weatherapi.com/v1/current.json?key=f93eb660b2424258bf5155016210712&q=${query}` + ); + + const data = await response.json(); + console.log(data); + setCurrentWeather(data); + }; + + // const router = useIonRouter(); + function handleBackClick() { + router.goBack(); + } + + return ( + + + + My Weather + + + getCurrentPosition()}> + + + + + + handleBackClick()}> + + + + + + + + + Dashboard + + + + + +

Here's your location based weather

+
+
+ +
+ {currentWeather ? ( + + ) : ( + + )} +
+
+
+ ); +} + +export default Tab1; diff --git a/03_source/mobile/src/pages/DemoAccordionTutorial/AppPages/Tab2.jsx b/03_source/mobile/src/pages/DemoAccordionTutorial/AppPages/Tab2.jsx new file mode 100644 index 0000000..216544f --- /dev/null +++ b/03_source/mobile/src/pages/DemoAccordionTutorial/AppPages/Tab2.jsx @@ -0,0 +1,81 @@ +import { + IonButton, + IonCol, + IonContent, + IonHeader, + IonPage, + IonRow, + IonSearchbar, + IonTitle, + IonToolbar, +} from '@ionic/react'; +import { useState } from 'react'; +import { CurrentWeather } from '../components/CurrentWeather'; + +function Tab2() { + const [search, setSearch] = useState(''); + const [currentWeather, setCurrentWeather] = useState(false); + + const performSearch = async () => { + getAddress(search); + }; + + const getAddress = async (city) => { + const response = await fetch( + `https://api.weatherapi.com/v1/current.json?key=f93eb660b2424258bf5155016210712&q=${city}&aqi=no` + ); + const data = await response.json(); + + if (data && data.current && data.location) { + setCurrentWeather(data); + } + }; + + return ( + + + + Search + + + + + + Search + + + + + + setSearch(e.target.value)} + /> + + + + + Search + + + + +
+ {currentWeather ? ( + + ) : ( +

Your search result will appear here

+ )} +
+
+
+ ); +} + +export default Tab2; diff --git a/03_source/mobile/src/pages/DemoAccordionTutorial/components/Accordion.jsx b/03_source/mobile/src/pages/DemoAccordionTutorial/components/Accordion.jsx new file mode 100644 index 0000000..c679c72 --- /dev/null +++ b/03_source/mobile/src/pages/DemoAccordionTutorial/components/Accordion.jsx @@ -0,0 +1,29 @@ +import { IonAccordion, IonAccordionGroup, IonIcon, IonItem, IonLabel, IonList } from '@ionic/react'; +import { topics } from '../data'; + +export const Accordion = () => { + return ( + + {topics.map((topic, index) => { + return ( + + + + {topic.header} + + + + {topic.options.map((option, index2) => { + return ( + + {option.label} + + ); + })} + + + ); + })} + + ); +}; diff --git a/03_source/mobile/src/pages/DemoAccordionTutorial/components/CurrentWeather/WeatherProperty.tsx b/03_source/mobile/src/pages/DemoAccordionTutorial/components/CurrentWeather/WeatherProperty.tsx new file mode 100644 index 0000000..52949af --- /dev/null +++ b/03_source/mobile/src/pages/DemoAccordionTutorial/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/DemoAccordionTutorial/components/CurrentWeather/index.tsx b/03_source/mobile/src/pages/DemoAccordionTutorial/components/CurrentWeather/index.tsx new file mode 100644 index 0000000..ceb4332 --- /dev/null +++ b/03_source/mobile/src/pages/DemoAccordionTutorial/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/DemoAccordionTutorial/components/SkeletonDashboard/index.tsx b/03_source/mobile/src/pages/DemoAccordionTutorial/components/SkeletonDashboard/index.tsx new file mode 100644 index 0000000..234fb9b --- /dev/null +++ b/03_source/mobile/src/pages/DemoAccordionTutorial/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/DemoAccordionTutorial/data.js b/03_source/mobile/src/pages/DemoAccordionTutorial/data.js new file mode 100644 index 0000000..457fe00 --- /dev/null +++ b/03_source/mobile/src/pages/DemoAccordionTutorial/data.js @@ -0,0 +1,120 @@ +import { bicycleOutline, fastFoodOutline, filmOutline, gameControllerOutline, libraryOutline } from 'ionicons/icons'; + +export const topics = [ + { + header: 'Attractions', + color: 'primary', + icon: filmOutline, + options: [ + { + label: 'Cinema', + }, + { + label: 'Bowling Alley', + }, + { + label: 'Crazy Golf', + }, + { + label: 'Theme Park', + }, + ], + }, + { + header: 'Dining', + color: 'success', + icon: fastFoodOutline, + options: [ + { + label: 'Breakfast & Brunch', + }, + { + label: 'New American', + }, + { + label: 'Sushi Bars', + }, + { + label: 'Filipino Food', + }, + { + label: 'Asian Fusion', + }, + { + label: 'Ramen Houses', + }, + { + label: 'Dinner Venues', + }, + ], + }, + { + header: 'Gaming', + color: 'warning', + icon: gameControllerOutline, + options: [ + { + label: 'Xbox', + }, + { + label: 'Playstation', + }, + { + label: 'Nintendo Switch', + }, + { + label: 'PC', + }, + { + label: 'Mobile', + }, + { + label: 'Dreamcast', + }, + ], + }, + { + header: 'Exercise', + color: 'secondary', + icon: bicycleOutline, + options: [ + { + label: 'Yoga', + }, + { + label: 'Pilates', + }, + { + label: 'Weight Training', + }, + { + label: 'Cardio', + }, + { + label: 'Zumba', + }, + ], + }, + { + header: 'Education', + color: 'danger', + icon: libraryOutline, + options: [ + { + label: 'School', + }, + { + label: 'High School', + }, + { + label: 'University Bachelors', + }, + { + label: 'University Masters', + }, + { + label: 'University pHD', + }, + ], + }, +]; diff --git a/03_source/mobile/src/pages/DemoAccordionTutorial/index.tsx b/03_source/mobile/src/pages/DemoAccordionTutorial/index.tsx new file mode 100644 index 0000000..d1512fc --- /dev/null +++ b/03_source/mobile/src/pages/DemoAccordionTutorial/index.tsx @@ -0,0 +1,54 @@ +import { IonIcon, IonLabel, IonRouterOutlet, IonTabBar, IonTabButton, IonTabs } from '@ionic/react'; + +import { cloudOutline, searchOutline } from 'ionicons/icons'; +import { Route, Redirect } from 'react-router'; + +import Tab1 from './AppPages/Tab1'; +import Tab2 from './AppPages/Tab2'; + +import Topic from './pages/Topic.jsx'; +import Home from './pages/Home.jsx'; + +import './style.scss'; + +function DemoAccordionTutorial() { + return ( + + + {/* + + + + + */} + + + + + + + + + + + + {/* */} + + + {/* + + + + Dashboard + + + + Search + + + */} + + ); +} + +export default DemoAccordionTutorial; diff --git a/03_source/mobile/src/pages/DemoAccordionTutorial/pages/Home.css b/03_source/mobile/src/pages/DemoAccordionTutorial/pages/Home.css new file mode 100644 index 0000000..e69de29 diff --git a/03_source/mobile/src/pages/DemoAccordionTutorial/pages/Home.jsx b/03_source/mobile/src/pages/DemoAccordionTutorial/pages/Home.jsx new file mode 100644 index 0000000..a0add98 --- /dev/null +++ b/03_source/mobile/src/pages/DemoAccordionTutorial/pages/Home.jsx @@ -0,0 +1,97 @@ +import { + IonAccordion, + IonAccordionGroup, + IonButton, + IonButtons, + IonContent, + IonHeader, + IonIcon, + IonItem, + IonLabel, + IonList, + IonPage, + IonTitle, + IonToolbar, + useIonRouter, +} from '@ionic/react'; +import { Accordion } from '../components/Accordion'; +import { chevronBackOutline } from 'ionicons/icons'; + +const Home = () => { + const router = useIonRouter(); + + function handleBackClick() { + router.goBack(); + } + + return ( + + + + Accordion + + + handleBackClick()}> + + + + + + + + + Accordion + + + handleBackClick()}> + + + + + + + + + {/* + + + Languages + + + + + English + + + Spanish + + + Italian + + + + + + + Languages 2 + + + + + English + + + Spanish + + + Italian + + + + */} + + + ); +}; + +export default Home; diff --git a/03_source/mobile/src/pages/DemoAccordionTutorial/pages/Topic.jsx b/03_source/mobile/src/pages/DemoAccordionTutorial/pages/Topic.jsx new file mode 100644 index 0000000..32beb84 --- /dev/null +++ b/03_source/mobile/src/pages/DemoAccordionTutorial/pages/Topic.jsx @@ -0,0 +1,39 @@ +import { IonBackButton, IonButtons, IonCol, IonContent, IonGrid, IonHeader, IonLabel, IonPage, IonRow, IonTitle, IonToolbar } from '@ionic/react'; +import { useParams } from 'react-router'; + +const Topic = () => { + + const { topic } = useParams(); + + return ( + + + + + + + + + { topic } + + + + + + { topic } + + + + + + + This is the page for the topic: { topic }. + + + + + + ); +}; + +export default Topic; diff --git a/03_source/mobile/src/pages/DemoAccordionTutorial/style.scss b/03_source/mobile/src/pages/DemoAccordionTutorial/style.scss new file mode 100644 index 0000000..d12d506 --- /dev/null +++ b/03_source/mobile/src/pages/DemoAccordionTutorial/style.scss @@ -0,0 +1,237 @@ +.demo-accordion-tutorial { + /* Ionic Variables and Theming. For more info, please see: +http://ionicframework.com/docs/theming/ */ + + /** Ionic CSS Variables **/ + * { + /** 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; + } + + @media (prefers-color-scheme: dark) { + /* + * Dark Colors + * ------------------------------------------- + */ + + body { + --ion-color-primary: #428cff; + --ion-color-primary-rgb: 66, 140, 255; + --ion-color-primary-contrast: #ffffff; + --ion-color-primary-contrast-rgb: 255, 255, 255; + --ion-color-primary-shade: #3a7be0; + --ion-color-primary-tint: #5598ff; + + --ion-color-secondary: #50c8ff; + --ion-color-secondary-rgb: 80, 200, 255; + --ion-color-secondary-contrast: #ffffff; + --ion-color-secondary-contrast-rgb: 255, 255, 255; + --ion-color-secondary-shade: #46b0e0; + --ion-color-secondary-tint: #62ceff; + + --ion-color-tertiary: #6a64ff; + --ion-color-tertiary-rgb: 106, 100, 255; + --ion-color-tertiary-contrast: #ffffff; + --ion-color-tertiary-contrast-rgb: 255, 255, 255; + --ion-color-tertiary-shade: #5d58e0; + --ion-color-tertiary-tint: #7974ff; + + --ion-color-success: #2fdf75; + --ion-color-success-rgb: 47, 223, 117; + --ion-color-success-contrast: #000000; + --ion-color-success-contrast-rgb: 0, 0, 0; + --ion-color-success-shade: #29c467; + --ion-color-success-tint: #44e283; + + --ion-color-warning: #ffd534; + --ion-color-warning-rgb: 255, 213, 52; + --ion-color-warning-contrast: #000000; + --ion-color-warning-contrast-rgb: 0, 0, 0; + --ion-color-warning-shade: #e0bb2e; + --ion-color-warning-tint: #ffd948; + + --ion-color-danger: #ff4961; + --ion-color-danger-rgb: 255, 73, 97; + --ion-color-danger-contrast: #ffffff; + --ion-color-danger-contrast-rgb: 255, 255, 255; + --ion-color-danger-shade: #e04055; + --ion-color-danger-tint: #ff5b71; + + --ion-color-dark: #f4f5f8; + --ion-color-dark-rgb: 244, 245, 248; + --ion-color-dark-contrast: #000000; + --ion-color-dark-contrast-rgb: 0, 0, 0; + --ion-color-dark-shade: #d7d8da; + --ion-color-dark-tint: #f5f6f9; + + --ion-color-medium: #989aa2; + --ion-color-medium-rgb: 152, 154, 162; + --ion-color-medium-contrast: #000000; + --ion-color-medium-contrast-rgb: 0, 0, 0; + --ion-color-medium-shade: #86888f; + --ion-color-medium-tint: #a2a4ab; + + --ion-color-light: #222428; + --ion-color-light-rgb: 34, 36, 40; + --ion-color-light-contrast: #ffffff; + --ion-color-light-contrast-rgb: 255, 255, 255; + --ion-color-light-shade: #1e2023; + --ion-color-light-tint: #383a3e; + } + + /* + * iOS Dark Theme + * ------------------------------------------- + */ + + .ios body { + --ion-background-color: #000000; + --ion-background-color-rgb: 0, 0, 0; + + --ion-text-color: #ffffff; + --ion-text-color-rgb: 255, 255, 255; + + --ion-color-step-50: #0d0d0d; + --ion-color-step-100: #1a1a1a; + --ion-color-step-150: #262626; + --ion-color-step-200: #333333; + --ion-color-step-250: #404040; + --ion-color-step-300: #4d4d4d; + --ion-color-step-350: #595959; + --ion-color-step-400: #666666; + --ion-color-step-450: #737373; + --ion-color-step-500: #808080; + --ion-color-step-550: #8c8c8c; + --ion-color-step-600: #999999; + --ion-color-step-650: #a6a6a6; + --ion-color-step-700: #b3b3b3; + --ion-color-step-750: #bfbfbf; + --ion-color-step-800: #cccccc; + --ion-color-step-850: #d9d9d9; + --ion-color-step-900: #e6e6e6; + --ion-color-step-950: #f2f2f2; + + --ion-item-background: #000000; + + --ion-card-background: #1c1c1d; + } + + .ios ion-modal { + --ion-background-color: var(--ion-color-step-100); + --ion-toolbar-background: var(--ion-color-step-150); + --ion-toolbar-border-color: var(--ion-color-step-250); + } + + /* + * Material Design Dark Theme + * ------------------------------------------- + */ + + .md body { + --ion-background-color: #121212; + --ion-background-color-rgb: 18, 18, 18; + + --ion-text-color: #ffffff; + --ion-text-color-rgb: 255, 255, 255; + + --ion-border-color: #222222; + + --ion-color-step-50: #1e1e1e; + --ion-color-step-100: #2a2a2a; + --ion-color-step-150: #363636; + --ion-color-step-200: #414141; + --ion-color-step-250: #4d4d4d; + --ion-color-step-300: #595959; + --ion-color-step-350: #656565; + --ion-color-step-400: #717171; + --ion-color-step-450: #7d7d7d; + --ion-color-step-500: #898989; + --ion-color-step-550: #949494; + --ion-color-step-600: #a0a0a0; + --ion-color-step-650: #acacac; + --ion-color-step-700: #b8b8b8; + --ion-color-step-750: #c4c4c4; + --ion-color-step-800: #d0d0d0; + --ion-color-step-850: #dbdbdb; + --ion-color-step-900: #e7e7e7; + --ion-color-step-950: #f3f3f3; + + --ion-item-background: #1e1e1e; + + --ion-toolbar-background: #1f1f1f; + + --ion-tab-bar-background: #1f1f1f; + + --ion-card-background: #1e1e1e; + } + } +}