Compare commits

...

8 Commits

437 changed files with 107341 additions and 7128 deletions

View File

@@ -1,6 +1,15 @@
{
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"printWidth": 100
"printWidth": 160,
"overrides": [
{
"files": "src/App.tsx",
"options": {
"printWidth": 240
}
}
]
}

View File

@@ -9,7 +9,11 @@ android {
apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
dependencies {
implementation project(':capacitor-barcode-scanner')
implementation project(':capacitor-clipboard')
implementation project(':capacitor-geolocation')
implementation project(':capacitor-preferences')
implementation project(':capacitor-share')
}

View File

@@ -2,5 +2,17 @@
include ':capacitor-android'
project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor')
include ':capacitor-barcode-scanner'
project(':capacitor-barcode-scanner').projectDir = new File('../node_modules/@capacitor/barcode-scanner/android')
include ':capacitor-clipboard'
project(':capacitor-clipboard').projectDir = new File('../node_modules/@capacitor/clipboard/android')
include ':capacitor-geolocation'
project(':capacitor-geolocation').projectDir = new File('../node_modules/@capacitor/geolocation/android')
include ':capacitor-preferences'
project(':capacitor-preferences').projectDir = new File('../node_modules/@capacitor/preferences/android')
include ':capacitor-share'
project(':capacitor-share').projectDir = new File('../node_modules/@capacitor/share/android')

View File

@@ -1,9 +1,9 @@
#!/usr/bin/env bash
while true; do
npm i -D
yarn -D
npm run dev
yarn run dev
echo "restarting..."
sleep 1

View File

@@ -11,7 +11,11 @@ install! 'cocoapods', :disable_input_output_paths => true
def capacitor_pods
pod 'Capacitor', :path => '../../node_modules/@capacitor/ios'
pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios'
pod 'CapacitorBarcodeScanner', :path => '../../node_modules/@capacitor/barcode-scanner'
pod 'CapacitorClipboard', :path => '../../node_modules/@capacitor/clipboard'
pod 'CapacitorGeolocation', :path => '../../node_modules/@capacitor/geolocation'
pod 'CapacitorPreferences', :path => '../../node_modules/@capacitor/preferences'
pod 'CapacitorShare', :path => '../../node_modules/@capacitor/share'
end
target 'App' do

File diff suppressed because it is too large Load Diff

View File

@@ -7,24 +7,35 @@
"private": true,
"dependencies": {
"@capacitor/android": "7.0.1",
"@capacitor/barcode-scanner": "^2.0.3",
"@capacitor/clipboard": "^7.0.1",
"@capacitor/core": "^7.0.0",
"@capacitor/geolocation": "^7.1.2",
"@capacitor/ios": "7.0.1",
"@capacitor/preferences": "^7.0.0",
"@capacitor/share": "^7.0.1",
"@hookform/resolvers": "^4.1.3",
"@ionic/react": "^8.5.0",
"@ionic/react-router": "^8.5.0",
"@mdx-js/react": "^3.1.0",
"@react-hook/window-size": "^3.1.1",
"@types/leaflet": "^1.9.17",
"@types/react-redux": "^7.1.34",
"axios": "^1.9.0",
"date-fns": "^2.25.0",
"ionicons": "^7.1.2",
"leaflet": "^1.9.4",
"pigeon-maps": "^0.22.1",
"pullstate": "^1",
"react": "19.0.0",
"react-color": "^2.19.3",
"react-confetti": "^6.4.0",
"react-dom": "19.0.0",
"react-hook-form": "^7.55.0",
"react-leaflet": "^5.0.0",
"react-markdown": "^10.1.0",
"react-qr-code": "^2.0.15",
"react-qr-reader": "^3.0.0-beta-1",
"react-redux": "^9.2.0",
"react-router": "^5.3.4",
"react-router-dom": "^5.3.4",
@@ -32,7 +43,8 @@
"react-use": "^17.6.0",
"reselect": "^4.0.0",
"sass": "^1.85.1",
"swiper": "^9.1.1",
"swiper": "^11.2.8",
"use-sound": "^5.0.0",
"zod": "^3.24.2"
},
"scripts": {
@@ -64,7 +76,7 @@
"@types/react-router-dom": "^5.3.3",
"@vitejs/plugin-react": "^4.3.4",
"lint-staged": "^13.2.0",
"prettier": "^2.8.6",
"prettier": "^3.5.3",
"typescript": "^5.8.2",
"vite": "^6.2.0"
},

Binary file not shown.

After

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -0,0 +1 @@
<svg width="350" height="140" xmlns="http://www.w3.org/2000/svg" style="background:#f6f7f9"><g fill="none" fill-rule="evenodd"><path fill="#F04141" style="mix-blend-mode:multiply" d="M61.905-34.23l96.194 54.51-66.982 54.512L22 34.887z"/><circle fill="#10DC60" style="mix-blend-mode:multiply" cx="155.5" cy="135.5" r="57.5"/><path fill="#3880FF" style="mix-blend-mode:multiply" d="M208.538 9.513l84.417 15.392L223.93 93.93z"/><path fill="#FFCE00" style="mix-blend-mode:multiply" d="M268.625 106.557l46.332-26.75 46.332 26.75v53.5l-46.332 26.75-46.332-26.75z"/><circle fill="#7044FF" style="mix-blend-mode:multiply" cx="299.5" cy="9.5" r="38.5"/><rect fill="#11D3EA" style="mix-blend-mode:multiply" transform="rotate(-60 148.47 37.886)" x="143.372" y="-7.056" width="10.196" height="89.884" rx="5.098"/><path d="M-25.389 74.253l84.86 8.107c5.498.525 9.53 5.407 9.004 10.905a10 10 0 0 1-.057.477l-12.36 85.671a10.002 10.002 0 0 1-11.634 8.42l-86.351-15.226c-5.44-.959-9.07-6.145-8.112-11.584l13.851-78.551a10 10 0 0 1 10.799-8.219z" fill="#7044FF" style="mix-blend-mode:multiply"/><circle fill="#0CD1E8" style="mix-blend-mode:multiply" cx="273.5" cy="106.5" r="20.5"/></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -0,0 +1 @@
<svg width="350" height="140" xmlns="http://www.w3.org/2000/svg" style="background:#f6f7f9"><g fill="none" fill-rule="evenodd"><path fill="#F04141" style="mix-blend-mode:multiply" d="M61.905-34.23l96.194 54.51-66.982 54.512L22 34.887z"/><circle fill="#10DC60" style="mix-blend-mode:multiply" cx="155.5" cy="135.5" r="57.5"/><path fill="#3880FF" style="mix-blend-mode:multiply" d="M208.538 9.513l84.417 15.392L223.93 93.93z"/><path fill="#FFCE00" style="mix-blend-mode:multiply" d="M268.625 106.557l46.332-26.75 46.332 26.75v53.5l-46.332 26.75-46.332-26.75z"/><circle fill="#7044FF" style="mix-blend-mode:multiply" cx="299.5" cy="9.5" r="38.5"/><rect fill="#11D3EA" style="mix-blend-mode:multiply" transform="rotate(-60 148.47 37.886)" x="143.372" y="-7.056" width="10.196" height="89.884" rx="5.098"/><path d="M-25.389 74.253l84.86 8.107c5.498.525 9.53 5.407 9.004 10.905a10 10 0 0 1-.057.477l-12.36 85.671a10.002 10.002 0 0 1-11.634 8.42l-86.351-15.226c-5.44-.959-9.07-6.145-8.112-11.584l13.851-78.551a10 10 0 0 1 10.799-8.219z" fill="#7044FF" style="mix-blend-mode:multiply"/><circle fill="#0CD1E8" style="mix-blend-mode:multiply" cx="273.5" cy="106.5" r="20.5"/></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@@ -0,0 +1 @@
<svg width="350" height="140" xmlns="http://www.w3.org/2000/svg" style="background:#f6f7f9"><g fill="none" fill-rule="evenodd"><path fill="#F04141" style="mix-blend-mode:multiply" d="M61.905-34.23l96.194 54.51-66.982 54.512L22 34.887z"/><circle fill="#10DC60" style="mix-blend-mode:multiply" cx="155.5" cy="135.5" r="57.5"/><path fill="#3880FF" style="mix-blend-mode:multiply" d="M208.538 9.513l84.417 15.392L223.93 93.93z"/><path fill="#FFCE00" style="mix-blend-mode:multiply" d="M268.625 106.557l46.332-26.75 46.332 26.75v53.5l-46.332 26.75-46.332-26.75z"/><circle fill="#7044FF" style="mix-blend-mode:multiply" cx="299.5" cy="9.5" r="38.5"/><rect fill="#11D3EA" style="mix-blend-mode:multiply" transform="rotate(-60 148.47 37.886)" x="143.372" y="-7.056" width="10.196" height="89.884" rx="5.098"/><path d="M-25.389 74.253l84.86 8.107c5.498.525 9.53 5.407 9.004 10.905a10 10 0 0 1-.057.477l-12.36 85.671a10.002 10.002 0 0 1-11.634 8.42l-86.351-15.226c-5.44-.959-9.07-6.145-8.112-11.584l13.851-78.551a10 10 0 0 1 10.799-8.219z" fill="#7044FF" style="mix-blend-mode:multiply"/><circle fill="#0CD1E8" style="mix-blend-mode:multiply" cx="273.5" cy="106.5" r="20.5"/></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -0,0 +1 @@
<svg width="350" height="140" xmlns="http://www.w3.org/2000/svg" style="background:#f6f7f9"><g fill="none" fill-rule="evenodd"><path fill="#F04141" style="mix-blend-mode:multiply" d="M61.905-34.23l96.194 54.51-66.982 54.512L22 34.887z"/><circle fill="#10DC60" style="mix-blend-mode:multiply" cx="155.5" cy="135.5" r="57.5"/><path fill="#3880FF" style="mix-blend-mode:multiply" d="M208.538 9.513l84.417 15.392L223.93 93.93z"/><path fill="#FFCE00" style="mix-blend-mode:multiply" d="M268.625 106.557l46.332-26.75 46.332 26.75v53.5l-46.332 26.75-46.332-26.75z"/><circle fill="#7044FF" style="mix-blend-mode:multiply" cx="299.5" cy="9.5" r="38.5"/><rect fill="#11D3EA" style="mix-blend-mode:multiply" transform="rotate(-60 148.47 37.886)" x="143.372" y="-7.056" width="10.196" height="89.884" rx="5.098"/><path d="M-25.389 74.253l84.86 8.107c5.498.525 9.53 5.407 9.004 10.905a10 10 0 0 1-.057.477l-12.36 85.671a10.002 10.002 0 0 1-11.634 8.42l-86.351-15.226c-5.44-.959-9.07-6.145-8.112-11.584l13.851-78.551a10 10 0 0 1 10.799-8.219z" fill="#7044FF" style="mix-blend-mode:multiply"/><circle fill="#0CD1E8" style="mix-blend-mode:multiply" cx="273.5" cy="106.5" r="20.5"/></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

@@ -0,0 +1 @@
<svg width="350" height="140" xmlns="http://www.w3.org/2000/svg" style="background:#f6f7f9"><g fill="none" fill-rule="evenodd"><path fill="#F04141" style="mix-blend-mode:multiply" d="M61.905-34.23l96.194 54.51-66.982 54.512L22 34.887z"/><circle fill="#10DC60" style="mix-blend-mode:multiply" cx="155.5" cy="135.5" r="57.5"/><path fill="#3880FF" style="mix-blend-mode:multiply" d="M208.538 9.513l84.417 15.392L223.93 93.93z"/><path fill="#FFCE00" style="mix-blend-mode:multiply" d="M268.625 106.557l46.332-26.75 46.332 26.75v53.5l-46.332 26.75-46.332-26.75z"/><circle fill="#7044FF" style="mix-blend-mode:multiply" cx="299.5" cy="9.5" r="38.5"/><rect fill="#11D3EA" style="mix-blend-mode:multiply" transform="rotate(-60 148.47 37.886)" x="143.372" y="-7.056" width="10.196" height="89.884" rx="5.098"/><path d="M-25.389 74.253l84.86 8.107c5.498.525 9.53 5.407 9.004 10.905a10 10 0 0 1-.057.477l-12.36 85.671a10.002 10.002 0 0 1-11.634 8.42l-86.351-15.226c-5.44-.959-9.07-6.145-8.112-11.584l13.851-78.551a10 10 0 0 1 10.799-8.219z" fill="#7044FF" style="mix-blend-mode:multiply"/><circle fill="#0CD1E8" style="mix-blend-mode:multiply" cx="273.5" cy="106.5" r="20.5"/></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 682 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -0,0 +1 @@
<svg width="350" height="140" xmlns="http://www.w3.org/2000/svg" style="background:#f6f7f9"><g fill="none" fill-rule="evenodd"><path fill="#F04141" style="mix-blend-mode:multiply" d="M61.905-34.23l96.194 54.51-66.982 54.512L22 34.887z"/><circle fill="#10DC60" style="mix-blend-mode:multiply" cx="155.5" cy="135.5" r="57.5"/><path fill="#3880FF" style="mix-blend-mode:multiply" d="M208.538 9.513l84.417 15.392L223.93 93.93z"/><path fill="#FFCE00" style="mix-blend-mode:multiply" d="M268.625 106.557l46.332-26.75 46.332 26.75v53.5l-46.332 26.75-46.332-26.75z"/><circle fill="#7044FF" style="mix-blend-mode:multiply" cx="299.5" cy="9.5" r="38.5"/><rect fill="#11D3EA" style="mix-blend-mode:multiply" transform="rotate(-60 148.47 37.886)" x="143.372" y="-7.056" width="10.196" height="89.884" rx="5.098"/><path d="M-25.389 74.253l84.86 8.107c5.498.525 9.53 5.407 9.004 10.905a10 10 0 0 1-.057.477l-12.36 85.671a10.002 10.002 0 0 1-11.634 8.42l-86.351-15.226c-5.44-.959-9.07-6.145-8.112-11.584l13.851-78.551a10 10 0 0 1 10.799-8.219z" fill="#7044FF" style="mix-blend-mode:multiply"/><circle fill="#0CD1E8" style="mix-blend-mode:multiply" cx="273.5" cy="106.5" r="20.5"/></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1 @@
<svg width="350" height="140" xmlns="http://www.w3.org/2000/svg" style="background:#f6f7f9"><g fill="none" fill-rule="evenodd"><path fill="#F04141" style="mix-blend-mode:multiply" d="M61.905-34.23l96.194 54.51-66.982 54.512L22 34.887z"/><circle fill="#10DC60" style="mix-blend-mode:multiply" cx="155.5" cy="135.5" r="57.5"/><path fill="#3880FF" style="mix-blend-mode:multiply" d="M208.538 9.513l84.417 15.392L223.93 93.93z"/><path fill="#FFCE00" style="mix-blend-mode:multiply" d="M268.625 106.557l46.332-26.75 46.332 26.75v53.5l-46.332 26.75-46.332-26.75z"/><circle fill="#7044FF" style="mix-blend-mode:multiply" cx="299.5" cy="9.5" r="38.5"/><rect fill="#11D3EA" style="mix-blend-mode:multiply" transform="rotate(-60 148.47 37.886)" x="143.372" y="-7.056" width="10.196" height="89.884" rx="5.098"/><path d="M-25.389 74.253l84.86 8.107c5.498.525 9.53 5.407 9.004 10.905a10 10 0 0 1-.057.477l-12.36 85.671a10.002 10.002 0 0 1-11.634 8.42l-86.351-15.226c-5.44-.959-9.07-6.145-8.112-11.584l13.851-78.551a10 10 0 0 1 10.799-8.219z" fill="#7044FF" style="mix-blend-mode:multiply"/><circle fill="#0CD1E8" style="mix-blend-mode:multiply" cx="273.5" cy="106.5" r="20.5"/></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 896 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View File

@@ -0,0 +1 @@
<svg width="350" height="140" xmlns="http://www.w3.org/2000/svg" style="background:#f6f7f9"><g fill="none" fill-rule="evenodd"><path fill="#F04141" style="mix-blend-mode:multiply" d="M61.905-34.23l96.194 54.51-66.982 54.512L22 34.887z"/><circle fill="#10DC60" style="mix-blend-mode:multiply" cx="155.5" cy="135.5" r="57.5"/><path fill="#3880FF" style="mix-blend-mode:multiply" d="M208.538 9.513l84.417 15.392L223.93 93.93z"/><path fill="#FFCE00" style="mix-blend-mode:multiply" d="M268.625 106.557l46.332-26.75 46.332 26.75v53.5l-46.332 26.75-46.332-26.75z"/><circle fill="#7044FF" style="mix-blend-mode:multiply" cx="299.5" cy="9.5" r="38.5"/><rect fill="#11D3EA" style="mix-blend-mode:multiply" transform="rotate(-60 148.47 37.886)" x="143.372" y="-7.056" width="10.196" height="89.884" rx="5.098"/><path d="M-25.389 74.253l84.86 8.107c5.498.525 9.53 5.407 9.004 10.905a10 10 0 0 1-.057.477l-12.36 85.671a10.002 10.002 0 0 1-11.634 8.42l-86.351-15.226c-5.44-.959-9.07-6.145-8.112-11.584l13.851-78.551a10 10 0 0 1 10.799-8.219z" fill="#7044FF" style="mix-blend-mode:multiply"/><circle fill="#0CD1E8" style="mix-blend-mode:multiply" cx="273.5" cy="106.5" r="20.5"/></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@@ -64,6 +64,33 @@ import ServiceAgreement from './pages/ServiceAgreement';
import paths from './paths';
import PrivacyAgreement from './pages/PrivacyAgreement';
import AppRoute from './AppRoute';
//
import DemoReactShop from './pages/DemoReactShop';
import DemoWeatherApp from './pages/DemoWeatherApp';
import DemoClubHouse from './pages/DemoClubHouse';
import DemoScoreBoard from './pages/DemoScoreBoard';
import DemoQuoteApp from './pages/DemoQuoteApp';
import DemoQrScanner from './pages/DemoQrScanner';
// DemoShopAppUi
import DemoShopAppUi from './pages/DemoShopAppUi';
// DemoDictionaryApp
import DemoDictionaryApp from './pages/DemoDictionaryApp';
// demo-recipe-app
import DemoRecipeApp from './pages/DemoRecipeApp';
// DemoSlidingProfile
import DemoSlidingProfile from './pages/DemoSlidingProfile';
// DemoQuizApp
import DemoQuizApp from './pages/DemoQuizApp';
import DemoBlogPostUi from './pages/DemoBlogPostUi';
import DemoReactTravelApp from './pages/DemoReactTravelApp';
import DemoPinterestFloatingTabBar from './pages/DemoPinterestFloatingTabBar';
import DemoRestaurantFinder from './pages/DemoRestaurantFinder';
import DemoReactOverlayHooks from './pages/DemoReactOverlayHooks';
import DemoReactSwitchTabs from './pages/DemoReactSwitchTabs';
import DemoReactPollApp from './pages/DemoReactPollApp';
import DemoReactWhatsAppClone from './pages/DemoReactWhatsAppClone';
setupIonicReact();
@@ -89,14 +116,7 @@ interface DispatchProps {
interface IonicAppProps extends StateProps, DispatchProps {}
const IonicApp: React.FC<IonicAppProps> = ({
darkMode,
schedule,
setIsLoggedIn,
setUsername,
loadConfData,
loadUserData,
}) => {
const IonicApp: React.FC<IonicAppProps> = ({ darkMode, schedule, setIsLoggedIn, setUsername, loadConfData, loadUserData }) => {
useEffect(() => {
loadUserData();
loadConfData();
@@ -119,10 +139,34 @@ const IonicApp: React.FC<IonicAppProps> = ({
<AppRoute />
{/* */}
<Route path="/tabs" render={() => <MainTabs />} />
<Route path={paths.DEMO_WEATHER_APP} render={() => <DemoWeatherApp />} />
{/* */}
{/* */}
{/* */}
{/* */}
<Route path={paths.DEMO_REACT_WHATSAPP_CLONE} render={() => <DemoReactWhatsAppClone />} />
<Route path={paths.DEMO_REACT_POLL_APP} render={() => <DemoReactPollApp />} />
<Route path={paths.DEMO_BLOG_POST_UI} render={() => <DemoBlogPostUi />} />
<Route path={paths.DEMO_CLUB_HOUSE} render={() => <DemoClubHouse />} />
<Route path={paths.DEMO_DICTIONARY_APP} render={() => <DemoDictionaryApp />} />
<Route path={paths.DEMO_PINTEREST_FLOATING_TAB_BAR} render={() => <DemoPinterestFloatingTabBar />} />
<Route path={paths.DEMO_QR_SCANNER} render={() => <DemoQrScanner />} />
<Route path={paths.DEMO_QUIZ_APP} render={() => <DemoQuizApp />} />
<Route path={paths.DEMO_QUOTE_APP} render={() => <DemoQuoteApp />} />
<Route path={paths.DEMO_REACT_OVERLAY_HOOKS} render={() => <DemoReactOverlayHooks />} />
<Route path={paths.DEMO_REACT_POLL_APP} render={() => <DemoReactPollApp />} />
<Route path={paths.DEMO_REACT_SHOP} render={() => <DemoReactShop />} />
<Route path={paths.DEMO_REACT_SWITCH_TABS} render={() => <DemoReactSwitchTabs />} />
<Route path={paths.DEMO_REACT_TRAVEL_APP} render={() => <DemoReactTravelApp />} />
<Route path={paths.DEMO_RECIPE_APP} render={() => <DemoRecipeApp />} />
<Route path={paths.DEMO_RESTAURANT_FINDER} render={() => <DemoRestaurantFinder />} />
<Route path={paths.DEMO_SCORE_BOARD} render={() => <DemoScoreBoard />} />
<Route path={paths.DEMO_SHOP_APP_UI} render={() => <DemoShopAppUi />} />
<Route path={paths.DEMO_SLIDING_PROFILE} render={() => <DemoSlidingProfile />} />
<Route path="/account" component={Account} />
<Route path="/login" component={Login} />
<Route path="/mylogin" component={MyLogin} />
@@ -131,7 +175,6 @@ const IonicApp: React.FC<IonicAppProps> = ({
<Route path="/support" component={Support} />
<Route path="/tutorial" component={Tutorial} />
{/* */}
<Route
path="/logout"
render={() => {

View File

@@ -7,14 +7,12 @@ import NotImplemented from './pages/NotImplemented';
import EventDetail from './pages/EventDetail';
import MemberProfile from './pages/MemberProfile';
import paths from './paths';
import Helloworld from './pages/Helloworld';
import Settings from './pages/Settings';
import ChangeLanguage from './pages/ChangeLanguage';
import ServiceAgreement from './pages/ServiceAgreement';
import PrivacyAgreement from './pages/PrivacyAgreement';
// import OrderDetails from './pages/OrderDetail';
import OrderDetail from './pages/OrderDetail';
import SpeakerDetail from './pages/SpeakerDetail';
const AppRoute: React.FC = () => {
return (

View File

@@ -10,6 +10,9 @@ import Favourites from './pages/Favourites';
import MyProfile from './pages/MyProfile';
import EventList from './pages/EventList';
import Helloworld from './pages/Helloworld';
// import WeatherDemo from './pages/WeatherDemo/Tab1';
import DemoList from './pages/DemoList';
// import DemoReactShop from './pages/DemoReactShop';
const TabAppRoute: React.FC = () => {
return (
@@ -33,6 +36,12 @@ const TabAppRoute: React.FC = () => {
{/* */}
<Route path={paths.PROFILE} render={() => <MyProfile />} exact={true} />
{/* */}
<Route path="/tabs/demo-list" render={() => <DemoList />} exact={true} />
{/* */}
<Route path="/tabs/helloworld" render={() => <Helloworld />} exact={true} />
</>
);
};

View File

@@ -15,13 +15,18 @@ import { endpoints } from '../../pages/MyLogin/endpoints';
export const loadUserData = () => async (dispatch: React.Dispatch<any>) => {
dispatch(setLoading(true));
const data = await getUserData();
dispatch(setData(data));
dispatch(setLoading(false));
};
export const setLoading = (isLoading: boolean) =>
({ type: 'set-user-loading', isLoading } as const);
({
type: 'set-user-loading',
isLoading,
} as const);
export const setData = (data: Partial<UserState>) =>
({
@@ -30,6 +35,7 @@ export const setData = (data: Partial<UserState>) =>
} as const);
export const logoutUser = () => async (dispatch: React.Dispatch<any>) => {
//
await setIsLoggedInData(false);
dispatch(setUsername());
};
@@ -44,6 +50,8 @@ export const setIsLoggedIn = (loggedIn: boolean) => async (dispatch: React.Dispa
export const setUsername = (username?: string) => async (dispatch: React.Dispatch<any>) => {
await setUsernameData(username);
console.log('setUsername triggered');
return {
type: 'set-username',
username,
@@ -52,6 +60,7 @@ export const setUsername = (username?: string) => async (dispatch: React.Dispatc
export const setAccessToken = (token?: string) => async (dispatch: React.Dispatch<any>) => {
await setAccessTokenData(token);
return {
type: 'set-access-token',
token,
@@ -120,5 +129,4 @@ export type UserActions =
| ActionType<typeof setHasSeenTutorial>
| ActionType<typeof setDarkMode>
| ActionType<typeof setAccessToken>
// | ActionType<typeof setSession>
| ActionType<typeof checkUserSession>;

View File

@@ -15,11 +15,9 @@ export function userReducer(state: UserState, action: UserActions): UserState {
return { ...state, darkMode: action.darkMode };
case 'set-is-loggedin':
return { ...state, isLoggedin: action.loggedIn };
case 'set-access-token':
return { ...state, token: action.token };
case 'check-user-session':
return { ...state, isSessionValid: action.sessionValid };
// case 'set-active-session':
// return { ...state, session: action.session };
// case 'set-access-token':
// return { ...state, token: action.token };
}
}

View File

@@ -1,9 +1,9 @@
export interface UserState {
isLoggedin: boolean;
username?: string;
darkMode: boolean;
hasSeenTutorial: boolean;
loading: boolean;
username?: string;
hasSeenTutorial: boolean;
darkMode: boolean;
isLoggedin: boolean;
isSessionValid: boolean;
session?: any;
token?: string;

View File

@@ -0,0 +1,7 @@
.view-post-footer {
background-color: white;
padding-left: 1rem;
padding-right: 1rem;
padding-bottom: 1rem;
}

View File

@@ -0,0 +1,90 @@
import {
IonBackButton,
IonBadge,
IonButton,
IonButtons,
IonCardSubtitle,
IonCardTitle,
IonCol,
IonContent,
IonFooter,
IonGrid,
IonHeader,
IonIcon,
IonNote,
IonPage,
IonRow,
IonText,
IonTitle,
IonToolbar,
} from '@ionic/react';
import { bookmarkOutline, shareOutline } from 'ionicons/icons';
import { useParams } from 'react-router';
import { blogPosts } from '../localData';
import './BlogPost.css';
const BlogPost = () => {
const { id } = useParams();
const post = blogPosts.filter((post) => parseInt(post.id) === parseInt(id))[0];
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Blog</IonTitle>
<IonButtons slot="start">
<IonBackButton text="Blog Posts" />
</IonButtons>
</IonToolbar>
</IonHeader>
<IonContent fullscreen>
<img src={post.image} alt="post header" />
<IonGrid className="ion-padding-start ion-padding-end">
<IonRow className="ion-align-items-center ion-justify-content-between">
<IonRow className="ion-align-items-center ion-justify-content-between">
<img src={post.authorImage} className="post-author-avatar" alt="post author" />
<IonCardSubtitle className="ion-no-margin ion-no-padding ion-margin-start">
{post.author}
</IonCardSubtitle>
</IonRow>
<IonNote>{post.date}</IonNote>
</IonRow>
<IonRow>
<IonCol size="12">
<IonCardTitle className="post-title">{post.title}</IonCardTitle>
</IonCol>
</IonRow>
<IonRow>
<IonCol size="12">
<IonText color="medium">{post.content}</IonText>
</IonCol>
</IonRow>
</IonGrid>
</IonContent>
<IonFooter className="view-post-footer">
<IonRow className="post-footer ion-align-self-center ion-justify-content-between">
<div>
<IonButton fill="clear" color="primary">
<IonIcon icon={shareOutline} />
</IonButton>
<IonButton fill="clear" color="primary">
<IonIcon icon={bookmarkOutline} />
</IonButton>
</div>
<div>
<IonBadge color="primary" className="post-category">
{post.category}
</IonBadge>
</div>
</IonRow>
</IonFooter>
</IonPage>
);
};
export default BlogPost;

View File

@@ -0,0 +1,51 @@
import {
IonButton,
IonButtons,
IonContent,
IonHeader,
IonIcon,
IonPage,
IonTitle,
IonToolbar,
useIonRouter,
} from '@ionic/react';
import { Post } from '../components/Post';
import { blogPosts } from '../localData';
import { chevronBackOutline } from 'ionicons/icons';
const Home = () => {
const router = useIonRouter();
function handleBackClick() {
router.goBack();
}
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Ionic Blog</IonTitle>
<IonButtons slot="start">
<IonButton onClick={() => handleBackClick()}>
<IonIcon icon={chevronBackOutline} color="primary" />
</IonButton>
</IonButtons>
</IonToolbar>
</IonHeader>
<IonContent fullscreen>
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">Ionic Blog</IonTitle>
</IonToolbar>
</IonHeader>
{blogPosts.map((post, index) => (
<Post post={post} key={`post_${index}`} />
))}
</IonContent>
</IonPage>
);
};
export default Home;

View File

@@ -0,0 +1,37 @@
.post-author-avatar {
height: 2rem;
width: 2rem;
border-radius: 500px;
}
.post-title {
font-size: 1.4rem;
margin-top: 0.75rem;
}
.post-content {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
.post-footer {
display: flex;
flex-direction: row;
justify-content: space-between;
align-content: center;
width: 100%;
border-top: 2px solid rgb(245, 245, 245);
margin-top: 2rem;
padding-top: 1rem;
}
.post-category {
margin-top: 1.1rem;
}
.post-image {
width: 100%;
}

View File

@@ -0,0 +1,57 @@
import {
IonBadge,
IonButton,
IonCard,
IonCardContent,
IonCardHeader,
IonCardSubtitle,
IonCardTitle,
IonIcon,
IonNote,
IonRow,
} from '@ionic/react';
import { bookmarkOutline, shareOutline } from 'ionicons/icons';
import './Post.css';
export const Post = ({ post }) => {
return (
<IonCard routerLink={`/demo-blog-post-ui/post/${post.id}`}>
<img src={post.image} alt="main post" className="post-image" />
<IonCardHeader>
<IonRow className="ion-align-items-center ion-justify-content-between">
<IonRow className="ion-align-items-center ion-justify-content-between">
<img src={post.authorImage} className="post-author-avatar" alt="post author" />
<IonCardSubtitle className="ion-no-margin ion-no-padding ion-margin-start">
{post.author}
</IonCardSubtitle>
</IonRow>
<IonNote>{post.date}</IonNote>
</IonRow>
<IonCardTitle className="post-title">{post.title}</IonCardTitle>
</IonCardHeader>
<IonCardContent>
<p className="post-content">{post.content}</p>
<IonRow className="post-footer ion-align-self-center ion-justify-content-between">
<div>
<IonButton fill="clear" color="primary">
<IonIcon icon={shareOutline} />
</IonButton>
<IonButton fill="clear" color="primary">
<IonIcon icon={bookmarkOutline} />
</IonButton>
</div>
<div>
<IonBadge color="primary" className="post-category">
{post.category}
</IonBadge>
</div>
</IonRow>
</IonCardContent>
</IonCard>
);
};

View File

@@ -0,0 +1,27 @@
import { IonIcon, IonLabel, IonRouterOutlet, IonTabBar, IonTabButton, IonTabs } from '@ionic/react';
import { cloudOutline, searchOutline } from 'ionicons/icons';
import { Route, Redirect } from 'react-router';
import Home from './AppPages/Home';
import BlogPost from './AppPages/BlogPost';
import './style.scss';
function DemoBlogPostUi() {
return (
<IonRouterOutlet className="demo-blog-post-ui">
<Route exact path="/demo-blog-post-ui/home">
<Home />
</Route>
<Route exact path="/demo-blog-post-ui/post/:id">
<BlogPost />
</Route>
<Redirect exact path="/demo-blog-post-ui" to="/demo-blog-post-ui/home" />
</IonRouterOutlet>
);
}
export default DemoBlogPostUi;

View File

@@ -0,0 +1,98 @@
export const blogPosts = [
{
"id": 1,
"title": "How to Convince Your Boss to Choose Ionic",
"title_link": "https://ionicframework.com/blog/convince-boss-choose-ionic-app-development/",
"date": "August 3, 2021",
"author": "By Kim Maida",
"authorImage": "https://ionicframework.com/blog/wp-content/uploads/2021/07/kim-maida-150x150.jpg",
"category": "ANNOUNCEMENTS",
"category_link": "https://ionicframework.com/blog//blog/category/announcements",
"image": "https://ionicframework.com/blog/wp-content/uploads/2021/07/how-to-convince-your-boss_image_1aug2021.png",
"content": "Greetings, friend! Youre a web developer, team lead, or engineering manager who has discovered that Ionic products are awesome. They have helped you build cross-platform applications quickly, made the app development process enjoyable, and solved important mobile development problems. You can see that Ionic would be extremely beneficial in your daily job, but are wondering how to convince your boss to endorse the adoption of new software. In a nutshell:"
},
{
"id": 2,
"title": "Ioniconf 2021 Conference Recap",
"title_link": "https://ionicframework.com/blog/ioniconf-2021-conference-recap/",
"date": "July 29, 2021",
"author": "By Mike Hartington",
"authorImage": "https://ionicframework.com/blog/wp-content/uploads/2018/08/mike-headshot-2-smaller-150x150.png",
"category": "ANNOUNCEMENTS",
"category_link": "https://ionicframework.com/blog//blog/category/announcements",
"image": "https://ionicframework.com/blog/wp-content/uploads/2021/06/og-imgx2.png",
"content": "And with that, Ioniconf 2021 has concluded! Ioniconf, our online conference for Ionic developers and the wider web development community, featured twelve expert Ionic speakers and was attended by many thousands of Ionic community members. Were thrilled by the communitys reception to the event and are already looking forward to our next event taking place in September. Read on for a recap and links to all recorded talks."
},
{
"id": 3,
"title": "Announcing Identity Vault 5.0",
"title_link": "https://ionicframework.com/blog/announcing-identity-vault-5-0/",
"date": "July 28, 2021",
"author": "By Dallas James",
"authorImage": "https://ionicframework.com/blog/wp-content/uploads/2021/07/dallas-james-150x150.jpg",
"category": "PRODUCT",
"category_link": "https://ionicframework.com/blog//blog/category/announcements",
"image": "https://ionicframework.com/blog/wp-content/uploads/2021/07/iv-5-feature-image.png",
"content": "Today Im excited to announce Identity Vault 5.0, the newest version of Ionics mobile biometrics solution. Featuring the latest in native security best practices, Identity Vault improves frontend security in any Ionic app by making it easy to add secure biometric authentication in minutes."
},
{
"id": 4,
"title": "Building with Stencil: Clock Component",
"title_link": "https://ionicframework.com/blog/building-with-stencil-clock-component/",
"date": "July 22, 2021",
"author": "By Kevin Hoyt",
"authorImage": "https://ionicframework.com/blog/wp-content/uploads/2021/07/2520666-150x150.jpg",
"category": "ANNOUNCEMENTS",
"category_link": "https://ionicframework.com/blog//blog/category/announcements",
"image": "https://ionicframework.com/blog/wp-content/uploads/2021/07/Image-from-iOS.png",
"content": "I have not seen a clock in a web-based user interface in a long time. This makes sense — they are pretty redundant these days. You have a clock on your watch, on your mobile device, and on your desktop, and those are just the digital versions available at a glance. Nonetheless, the process of building a clock can reveal a lot about how a platform works."
},
{
"id": 5,
"title": "Building with Stencil: Calendar Component",
"title_link": "https://ionicframework.com/blog/building-with-stencil-calendar-component/",
"date": "July 19, 2021",
"author": "By Kevin Hoyt",
"authorImage": "https://ionicframework.com/blog/wp-content/uploads/2021/07/2520666-150x150.jpg",
"category": "TUTORIALS",
"category_link": null,
"image": "https://ionicframework.com/blog/wp-content/uploads/2021/07/ionic-blog-post-image_first-look-01.png",
"content": "Take a look at the month view of a calendar and you will see several rows of numbers. The numbers themselves, increasing in value one after the other, are arranged in columns. HTML and CSS provide us with a number of tools to display content in rows and columns. Making a calendar component should be easy, right? Right?"
},
{
"id": 6,
"title": "Introducing the New Overlay Hooks for Ionic React",
"title_link": "https://ionicframework.com/blog/introducing-the-new-overlay-hooks-for-ionic-react/",
"date": "July 14, 2021",
"author": "By Ely Lucas",
"authorImage": "https://secure.gravatar.com/avatar/45ad19965b4bde97e9f4396ea01ed184?s=32&r=g",
"category": "ENGINEERING",
"category_link": null,
"image": "https://ionicframework.com/blog/wp-content/uploads/2021/07/react-overlay-hooks-feature-image.png",
"content": "Hello Friends! We know everyone is excited about the new features in Ionic Framework 6.0 beta, but that doesnt mean were done with V5! In Ionic React 5.6, we packaged up a new set of hooks for controlling our overlay components that we think you might like. What is an overlay you ask? Its the term we give components that display over your current content, such as alerts, modals, toasts, etc."
},
{
"id": 7,
"title": "The Future of Stencil: Expanded Team, New Software Platform, and More",
"title_link": "https://ionicframework.com/blog/the-future-of-stencil-expanded-team-new-software-platform-and-more/",
"date": "July 7, 2021",
"author": "By Nick Hyatt",
"authorImage": "https://ionicframework.com/blog/wp-content/uploads/2018/11/Nick-Hyatt-Headshot-150x150.jpeg",
"category": "ANNOUNCEMENTS",
"category_link": null,
"image": "https://ionicframework.com/blog/wp-content/uploads/2021/07/stencil-future-feature-image.png",
"content": "Today Im excited to share some news about Stencil, Ionics open source toolchain that generates small, fast, and 100% standards-based Web Components that run in every browser. As you might have noticed, weve been actively increasing our investments across the entire Ionic App Platform, including the recent launch of Capacitor 3.0, Ionic Portals, tons of Appflow improvements, and the upcoming Ionic Framework v6."
},
{
"id": 8,
"title": "Announcing the Ionic Framework v6 Beta",
"title_link": "https://ionicframework.com/blog/announcing-the-ionic-framework-v6-beta/",
"date": "June 29, 2021",
"author": "By Liam DeBeasi",
"authorImage": "https://ionicframework.com/blog/wp-content/uploads/2020/01/ZNK4lRAJ_400x400-150x150.jpg",
"category": "ANNOUNCEMENTS",
"category_link": null,
"image": "https://ionicframework.com/blog/wp-content/uploads/2021/06/framework6-feature-image.png",
"content": "Earlier this week I had the privilege of giving the Ionic Framework Update at Ioniconf 2021 where we announced the Ionic Framework v6 beta. Ionic Framework has come far from its roots as an AngularJS-only UI library to a truly cross-platform framework for building Web Native applications. As we look to the future of Ionic Framework, lets talk about some of the improvements coming in Framework v6 and how you can get access to these improvements today."
}
];

View File

@@ -0,0 +1,79 @@
.demo-blog-post-ui {
/* 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;
}
}

View File

@@ -0,0 +1,12 @@
.extra-padding {
padding-right: 1.3rem !important;
padding-left: 1.3rem !important;
}
.title {
font-weight: 600;
font-size: 1.2rem;
margin-bottom: 0.5rem;
}

View File

@@ -0,0 +1,90 @@
import {
IonButton,
IonButtons,
IonCol,
IonContent,
IonGrid,
IonHeader,
IonIcon,
IonPage,
IonRow,
IonText,
IonTitle,
IonToolbar,
useIonRouter,
} from '@ionic/react';
import { chevronBack, personOutline } from 'ionicons/icons';
import { useStoreState } from 'pullstate';
import { TalkStore } from '../store';
import { getTalks } from '../store/Selectors';
import './Tab1.css';
import { TalkCard } from '../components/TalkCard';
import { useRef } from 'react';
const Tab1 = () => {
const pageRef = useRef();
const talks = useStoreState(TalkStore, getTalks);
const router = useIonRouter();
function handleBackClick() {
router.goBack();
}
return (
<IonPage ref={pageRef}>
<IonHeader>
<IonToolbar>
<IonTitle>All Rooms</IonTitle>
<IonButtons slot="end">
<IonButton>
<IonIcon icon={personOutline} />
</IonButton>
</IonButtons>
<IonButtons slot="start">
<IonButton onclick={handleBackClick}>
<IonIcon icon={chevronBack} />
</IonButton>
</IonButtons>
</IonToolbar>
</IonHeader>
<IonContent fullscreen>
<IonGrid className="ion-padding-start ion-padding-end extra-padding ion-padding-bottom ion-margin-bottom">
<IonRow>
<IonCol size="12">
<IonText color="dark">
<p className="title">Upcoming</p>
</IonText>
</IonCol>
</IonRow>
<IonRow>
<IonCol size="12">
<TalkCard upcoming={true} talk={talks[0]} pageRef={pageRef} />
</IonCol>
</IonRow>
<IonRow>
<IonCol size="12">
<IonText color="dark">
<p className="title">Happening Now</p>
</IonText>
</IonCol>
</IonRow>
<IonRow>
<IonCol size="12">
{talks.map((talk, talkIndex) => {
return talkIndex > 0 && <TalkCard key={talkIndex} talk={talk} pageRef={pageRef} />;
})}
</IonCol>
</IonRow>
</IonGrid>
</IonContent>
</IonPage>
);
};
export default Tab1;

View File

@@ -0,0 +1,23 @@
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/react';
import './Tab2.css';
const Tab2 = () => {
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>TO DO :)</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent fullscreen>
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">TO DO :)</IonTitle>
</IonToolbar>
</IonHeader>
</IonContent>
</IonPage>
);
};
export default Tab2;

View File

@@ -0,0 +1,23 @@
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/react';
import './Tab3.css';
const Tab3 = () => {
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>TO DO :)</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent fullscreen>
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">TO DO :)</IonTitle>
</IonToolbar>
</IonHeader>
</IonContent>
</IonPage>
);
};
export default Tab3;

View File

@@ -0,0 +1,100 @@
import { IonCardSubtitle, IonIcon, IonModal, IonNote, IonRow, useIonModal } from "@ionic/react";
import { bulb, micOutline, personOutline } from "ionicons/icons";
import { useStoreState } from "pullstate";
import { useEffect, useState } from "react";
import { CategoryStore } from '../store';
import { getPeople } from "../store/PeopleStore";
import { getCategory } from '../store/Selectors';
import styles from "./TalkCard.module.css";
import { TalkModal } from "./TalkModal";
export const TalkCard = ({ upcoming = false, talk, pageRef }) => {
const talkCategory = useStoreState(CategoryStore, getCategory(talk.category_id));
const [ speakers, setSpeakers ] = useState([]);
const [ showModal, setShowModal ] = useState(false);
useEffect(() => {
setSpeakers(getPeople(talk.speakers));
}, [ talk ]);
// const [ present, dismiss ] = useIonModal(TalkModal, {
// dismiss: () => dismiss(),
// talk,
// speakers,
// category: talkCategory
// });
// const handleShowTalk = () => {
// console.log("in here");
// present({
// // presentingElement: pageRef.current
// });
// }
return (
<>
<div className={ `${ styles.talkCard } ${ upcoming && styles.upcomingCard }` } onClick={ () => setShowModal(true) }>
<div className={ styles.cardTitle }>
<IonIcon color={ upcoming ? "primary" : "white" } icon={ bulb } />
<IonCardSubtitle color={ upcoming ? "light" : "primary" }>{ talkCategory.name } talks</IonCardSubtitle>
</div>
<div className={ styles.talkTitle }>
<h3>{ talk.title }</h3>
</div>
{ !upcoming &&
<IonRow className={ styles.talkSpeakers }>
{ speakers.map((speaker, index) => {
return (
<div key={ `speaker_${ index }` } className={ styles.talkSpeaker }>
<img src={ speaker.image } alt="avatar" />
</div>
);
})}
</IonRow>
}
{ upcoming &&
<div className={ styles.talkDate }>
<IonNote color="secondary">{ talk.time }</IonNote>
<div className={ styles.detailCount }>
<IonIcon icon={ micOutline } color="light " />
<span>{ talk.speakers } Speakers</span>
</div>
</div>
}
{ !upcoming &&
<div className={ styles.talkDetails }>
<div className={ styles.detailCount }>
<IonIcon icon={ micOutline } color="primary" />
<span>{ talk.speakers } Speakers</span>
</div>
<div className={ styles.detailCount }>
<IonIcon icon={ personOutline } color="primary" />
<span>{ talk.audience } Audience</span>
</div>
</div>
}
</div>
<IonModal isOpen={ showModal } onDidDismiss={ () => setShowModal(false) } presentingElement={ pageRef.current }>
<TalkModal dismiss={ () => setShowModal(false) } speakers={ speakers } talk={ talk } category={ talkCategory } />
</IonModal>
</>
);
}

View File

@@ -0,0 +1,105 @@
.talkCard {
display: flex;
flex-direction: column;
border-radius: 10px;
padding: 2rem;
box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.1);
background-color: white;
}
.talkCard:not(:first-child) {
margin-top: 2rem;
}
.upcomingCard {
background-color: var(--ion-color-primary);
color: white;
}
.cardTitle {
display: flex;
flex-direction: row;
align-content: center;
align-items: center;
color: white;
}
.cardTitle ion-icon {
border-radius: 500px;
padding: 0.2rem;
margin-right: 0.75rem;
background-color: var(--ion-color-primary);
margin-top: -0.2rem;
}
.upcomingCard .cardTitle ion-icon {
background-color: white;
}
.talkTitle h3 {
font-size: 1.3rem !important;
font-weight: 600;
}
.talkDate {
display: flex;
justify-content: space-between;
align-items: center;
align-content: center;
margin-top: 0.5rem;
}
.talkSpeakers {
display: flex;
flex-direction: row;
margin-top: 0.5rem;
}
.talkSpeaker {
display: flex;
align-items: center;
justify-content: center;
height: 3.5rem;
width: 3.5rem;
border-radius: 12px;
margin-right: 0.2rem;
background-color: var(--ion-color-primary);
}
.talkSpeaker img {
height: 3rem;
width: 3rem;
}
.talkDetails {
display: flex;
justify-content: space-between;
margin-top: 1.5rem;
}
.detailCount {
display: flex;
align-content: center;
align-items: center;
font-weight: 500;
font-size: 0.9rem;
}
.detailCount ion-icon {
font-size: 1.2rem;
margin-right: 0.3rem;
}

View File

@@ -0,0 +1,98 @@
import { IonButton, IonButtons, IonCardSubtitle, IonCol, IonContent, IonGrid, IonHeader, IonIcon, IonPage, IonRow, IonTitle, IonToolbar } from "@ionic/react";
import { bulb, exitOutline, micOutline, personOutline } from "ionicons/icons";
import { useStoreState } from "pullstate";
import { PeopleStore } from "../store";
import { getAllPeople } from "../store/Selectors";
import styles from "./TalkModal.module.css";
export const TalkModal = ({ dismiss, talk, category, speakers }) => {
const people = useStoreState(PeopleStore, getAllPeople);
return (
<IonPage className="talk-modal">
<IonHeader>
<IonToolbar>
<IonTitle>Talk Room</IonTitle>
<IonButtons slot="end">
<IonButton color="primary" onClick={ dismiss }>
<IonIcon icon={ exitOutline } />
{/* Leave Room */}
</IonButton>
</IonButtons>
</IonToolbar>
</IonHeader>
<IonContent className={ styles.modal }>
<IonGrid className="ion-padding-start ion-padding-end ion-margin-start ion-margin-end">
<IonRow>
<IonCol size="12">
<div className={ styles.cardTitle }>
<IonIcon color="white" icon={ bulb } />
<IonCardSubtitle color="primary">{ category.name } talks</IonCardSubtitle>
</div>
</IonCol>
</IonRow>
<IonRow className={ styles.talkTitle }>
<IonCol size="12">
<h1>{ talk.title }</h1>
</IonCol>
</IonRow>
<IonRow>
<IonCol size="12">
<div className={ styles.detailCount }>
<IonIcon icon={ micOutline } color="primary" />
<span>{ talk.speakers } Speakers</span>
</div>
</IonCol>
</IonRow>
<IonRow className={ styles.talkSpeakers }>
{ speakers.map((speaker, index) => {
return (
<IonCol className={ styles.speakerContainer }>
<div key={ `speaker_${ index }` } className={ `${ styles.talkSpeaker } ${ index === 0 && styles.activeSpeaker }` }>
<img src={ speaker.image } alt="avatar" />
</div>
<p>{ speaker.name.split(" ")[0] }</p>
</IonCol>
);
})}
</IonRow>
<IonRow>
<IonCol size="12">
<div className={ styles.detailCount }>
<IonIcon icon={ personOutline } color="primary" />
<span>{ talk.audience } Audience</span>
</div>
</IonCol>
</IonRow>
<IonRow className={ styles.talkSpeakers }>
{ [ ...Array(talk.audience)].map((audience, index) => {
return (
<IonCol size="3" className={ `${ styles.speakerContainer } ${ styles.audienceContainer }` }>
<div key={ `speaker_${ index }` } className={ styles.talkSpeaker }>
<img src={ people[Math.floor(Math.random() * 30)].image } alt="avatar" />
</div>
<p>{ people[Math.floor(Math.random() * 30)].name.split(" ")[0] }</p>
</IonCol>
);
})}
</IonRow>
</IonGrid>
</IonContent>
</IonPage>
);
}

View File

@@ -0,0 +1,150 @@
.talkCard {
display: flex;
flex-direction: column;
border-radius: 10px;
padding: 2rem;
box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.1);
background-color: white;
}
.talkCard:not(:first-child) {
margin-top: 2rem;
}
.upcomingCard {
background-color: var(--ion-color-primary);
color: white;
}
.cardTitle {
display: flex;
flex-direction: row;
align-content: center;
align-items: center;
color: white;
}
.cardTitle ion-icon {
border-radius: 500px;
padding: 0.2rem;
margin-right: 0.75rem;
background-color: var(--ion-color-primary);
margin-top: -0.2rem;
}
.upcomingCard .cardTitle ion-icon {
background-color: white;
}
.talkTitle {
margin-top: -1rem;
}
.talkTitle h3 {
font-size: 1.3rem !important;
font-weight: 600;
}
.talkDate {
display: flex;
justify-content: space-between;
align-items: center;
align-content: center;
margin-top: 0.5rem;
}
.talkSpeakers {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-top: 0.5rem;
margin-bottom: 1.5rem;
}
.speakerContainer {
display: flex;
flex-direction: column;
align-content: center;
align-items: center;
justify-content: space-between;
}
.audienceContainer {
margin-bottom: 1rem;
/* margin: 0.5rem; */
}
.talkSpeaker {
display: flex;
align-items: center;
justify-content: center;
height: 3.5rem;
width: 3.5rem;
border-radius: 12px;
margin-right: 0.2rem;
background-color: var(--ion-color-primary);
}
.audienceContainer .talkSpeaker {
background-color: #f2efe5;
border: 2px solid #dfd9c7;
}
.talkSpeaker img {
height: 3rem;
width: 3rem;
}
.speakerContainer p {
margin: 0;
padding: 0;
margin-top: 0.2rem;
font-weight: 500;
font-size: 0.9rem;
}
.talkDetails {
display: flex;
justify-content: space-between;
margin-top: 1.5rem;
}
.detailCount {
display: flex;
align-content: center;
align-items: center;
font-weight: 600;
font-size: 0.9rem;
margin-top: 1rem;
margin-bottom: 0.3rem;
}
.detailCount ion-icon {
font-size: 1.2rem;
margin-right: 0.3rem;
margin-left: -0.4rem;
}
.activeSpeaker {
border: 3px solid rgb(255, 187, 0);
}

View File

@@ -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 (
<IonCol size="6">
<IonRow className="ion-justify-content-center ion-align-items-center">
<IonCol size="3">
{!property.isIcon && (
<img alt={property.alt} src={property.icon} height="32" width="32" />
)}
{property.isIcon && (
<IonIcon icon={property.icon} color="medium" style={{ fontSize: '2rem' }} />
)}
</IonCol>
<IonCol size="9">
<IonCardSubtitle>{property.label}</IonCardSubtitle>
<IonNote>{property.value}</IonNote>
</IonCol>
</IonRow>
</IonCol>
);
};

Some files were not shown because too many files have changed in this diff Show More