implemented vite caching and added adaptive agriculture logos and manifest
5437
package-lock.json
generated
|
|
@ -67,8 +67,9 @@
|
||||||
"save-svg-as-png": "^1.4.17",
|
"save-svg-as-png": "^1.4.17",
|
||||||
"typescript": "^5.5.3",
|
"typescript": "^5.5.3",
|
||||||
"typescript-eslint": "^8.7.0",
|
"typescript-eslint": "^8.7.0",
|
||||||
"vite": "^5.4.8",
|
"vite": "^6.2.0",
|
||||||
|
"vite-plugin-pwa": "^0.21.1",
|
||||||
"vite-tsconfig-paths": "^5.1.2",
|
"vite-tsconfig-paths": "^5.1.2",
|
||||||
"vitest": "^2.1.3"
|
"vitest": "^3.0.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
BIN
public/AdaptiveAgriculture/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
public/AdaptiveAgriculture/android-chrome-256x256.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
public/AdaptiveAgriculture/android-chrome-512x512.png
Normal file
|
After Width: | Height: | Size: 70 KiB |
BIN
public/AdaptiveAgriculture/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
9
public/AdaptiveAgriculture/browserconfig.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<browserconfig>
|
||||||
|
<msapplication>
|
||||||
|
<tile>
|
||||||
|
<square150x150logo src="/mstile-150x150.png"/>
|
||||||
|
<TileColor>#000000</TileColor>
|
||||||
|
</tile>
|
||||||
|
</msapplication>
|
||||||
|
</browserconfig>
|
||||||
BIN
public/AdaptiveAgriculture/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 1 KiB |
BIN
public/AdaptiveAgriculture/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
public/AdaptiveAgriculture/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
37
public/AdaptiveAgriculture/manifest.json
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
{
|
||||||
|
"name": "Adaptive Agriculture",
|
||||||
|
"short_name": "Adaptive Ag",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "favicon.ico",
|
||||||
|
"sizes": "48x48",
|
||||||
|
"type": "image/x-icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "android-chrome-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "android-chrome-256x256.png",
|
||||||
|
"sizes": "256x256",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "android-chrome-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "maskable_icon.png",
|
||||||
|
"sizes": "196x196",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "any maskable"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"start_url": "/",
|
||||||
|
"theme_color": "#272727",
|
||||||
|
"background_color": "#303030",
|
||||||
|
"display": "standalone",
|
||||||
|
"orientation": "any"
|
||||||
|
}
|
||||||
BIN
public/AdaptiveAgriculture/maskable_icon.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
public/AdaptiveAgriculture/mstile-150x150.png
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
83
public/AdaptiveAgriculture/safari-pinned-tab.svg
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||||
|
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||||
|
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="266.000000pt" height="266.000000pt" viewBox="0 0 266.000000 266.000000"
|
||||||
|
preserveAspectRatio="xMidYMid meet">
|
||||||
|
<metadata>
|
||||||
|
Created by potrace 1.11, written by Peter Selinger 2001-2013
|
||||||
|
</metadata>
|
||||||
|
<g transform="translate(0.000000,266.000000) scale(0.100000,-0.100000)"
|
||||||
|
fill="#000000" stroke="none">
|
||||||
|
<path d="M667 2014 c-1 -1 -22 -4 -47 -8 -122 -15 -222 -59 -313 -135 -192
|
||||||
|
-161 -264 -381 -212 -649 5 -30 55 -141 77 -174 10 -14 18 -29 18 -33 0 -13
|
||||||
|
162 -165 176 -165 7 0 17 -8 23 -17 5 -10 13 -17 18 -17 4 1 17 -2 28 -6 11
|
||||||
|
-4 22 -7 25 -7 3 0 16 -6 30 -13 14 -8 36 -16 50 -18 13 -2 28 -8 31 -14 4 -6
|
||||||
|
12 -7 19 -3 8 5 19 1 28 -11 11 -15 13 -15 9 -2 -4 11 -1 15 11 13 10 -1 16
|
||||||
|
-10 15 -21 -1 -17 0 -18 11 -2 13 18 121 28 147 13 8 -4 11 -4 6 0 -7 8 78 37
|
||||||
|
115 38 9 1 14 6 11 11 -4 5 1 7 10 3 10 -3 17 -2 17 3 0 6 7 10 15 10 8 0 15
|
||||||
|
5 15 11 0 5 4 8 9 4 5 -3 8 -15 6 -28 -7 -39 8 -49 74 -48 41 0 61 -4 61 -12
|
||||||
|
0 -8 3 -8 9 1 4 8 19 13 32 12 49 -4 152 0 146 6 -3 4 -2 15 4 25 7 14 6 19
|
||||||
|
-2 19 -8 0 -8 4 1 15 8 9 9 15 2 15 -11 0 -9 31 3 50 3 6 0 10 -7 10 -9 0 -9
|
||||||
|
3 2 10 11 7 11 10 2 10 -9 0 -10 5 -3 18 5 10 6 23 2 30 -6 10 -7 81 -1 107 1
|
||||||
|
6 1 12 0 15 -2 6 -6 70 -3 70 8 0 51 -105 46 -113 -3 -6 -1 -7 4 -4 6 4 18 -3
|
||||||
|
26 -16 64 -98 231 -218 337 -242 8 -2 31 -9 50 -14 19 -6 69 -11 110 -11 47 0
|
||||||
|
81 -5 89 -12 10 -11 12 -10 9 1 -2 7 4 15 12 16 8 2 31 6 50 10 19 3 45 7 57
|
||||||
|
8 12 0 20 4 17 8 -6 11 64 32 77 23 7 -4 9 -3 5 4 -3 6 -2 13 3 16 5 3 9 -10
|
||||||
|
8 -30 -1 -20 5 -39 12 -44 8 -4 10 -14 7 -21 -4 -8 -1 -6 7 4 17 20 47 22 66
|
||||||
|
5 10 -10 12 -10 7 -1 -9 16 106 16 116 -1 6 -8 8 -8 8 2 0 7 14 12 35 12 19 0
|
||||||
|
35 -5 35 -11 0 -6 9 -1 19 12 11 13 16 26 13 29 -10 8 -10 50 0 50 5 0 5 8 1
|
||||||
|
18 -10 21 -10 93 0 109 4 6 3 15 -3 18 -8 5 -8 11 0 20 8 9 8 15 0 20 -7 4 -7
|
||||||
|
12 0 25 7 13 6 20 -3 23 -9 4 -9 6 1 6 7 1 10 6 7 12 -11 16 -12 69 -3 69 5 0
|
||||||
|
5 8 -1 17 -5 10 -5 26 0 40 5 13 5 23 1 23 -5 0 -7 18 -5 40 l3 40 -215 0
|
||||||
|
-215 0 -1 -72 c-1 -40 -1 -78 0 -85 2 -15 -42 -45 -95 -66 -63 -24 -175 -17
|
||||||
|
-240 16 -81 41 -168 146 -148 179 4 7 3 8 -4 4 -8 -5 -12 1 -13 16 0 13 -3 32
|
||||||
|
-5 43 -6 25 -5 96 2 107 3 4 7 17 9 29 9 47 77 135 96 123 7 -4 9 -3 6 2 -3 6
|
||||||
|
-3 14 1 19 14 19 94 56 123 57 16 1 29 6 30 12 0 6 4 2 9 -9 7 -16 9 -17 9 -3
|
||||||
|
1 14 8 16 39 12 68 -10 81 -14 85 -32 4 -16 5 -16 6 1 0 10 6 15 11 12 6 -4 8
|
||||||
|
-11 4 -16 -3 -5 -2 -9 3 -8 27 5 47 -6 87 -45 42 -42 95 -126 79 -126 -4 0 -2
|
||||||
|
-5 4 -11 6 -6 32 -11 57 -12 26 0 46 -5 46 -11 0 -8 3 -8 8 0 9 14 123 15 141
|
||||||
|
0 11 -8 13 -8 8 0 -4 7 5 11 25 12 42 1 49 11 37 55 -5 20 -7 42 -3 49 4 7 3
|
||||||
|
8 -4 4 -16 -10 -15 17 1 33 10 10 8 11 -7 5 -16 -6 -18 -4 -12 11 4 11 4 16 0
|
||||||
|
12 -4 -4 -16 12 -27 35 -21 45 -84 134 -110 157 -9 7 -14 18 -10 25 3 6 3 8
|
||||||
|
-1 4 -7 -6 -58 29 -123 82 -7 6 -15 10 -18 10 -3 0 -26 9 -50 20 -61 28 -190
|
||||||
|
56 -250 54 -67 -2 -154 -12 -165 -19 -6 -3 -20 -8 -31 -10 -12 -3 -39 -13 -60
|
||||||
|
-25 -22 -11 -39 -17 -39 -15 0 3 -24 -11 -52 -32 -125 -87 -194 -174 -254
|
||||||
|
-318 l-16 -40 -8 28 c-5 16 -22 54 -39 86 -17 32 -27 62 -23 66 4 5 1 5 -5 1
|
||||||
|
-7 -4 -13 -2 -13 3 0 19 -147 159 -189 181 -25 12 -39 25 -35 32 4 7 3 8 -5 4
|
||||||
|
-7 -4 -28 0 -47 9 -19 9 -44 18 -54 21 -11 2 -30 7 -42 10 -51 12 -183 25
|
||||||
|
-191 18z m23 -328 c0 7 13 10 33 7 35 -4 72 -11 72 -13 0 -1 7 -3 15 -5 29 -5
|
||||||
|
85 -43 82 -55 -1 -6 2 -9 7 -5 14 8 83 -66 76 -83 -2 -7 -1 -11 3 -8 5 3 17
|
||||||
|
-18 27 -47 66 -182 -71 -388 -268 -403 -64 -5 -157 11 -157 28 0 5 -4 7 -9 4
|
||||||
|
-10 -7 -63 32 -97 70 -28 32 -71 110 -55 100 5 -4 3 7 -6 24 -21 44 -22 63 -4
|
||||||
|
78 9 7 12 11 6 10 -12 -4 -15 4 -15 43 0 20 4 28 12 23 7 -4 8 -3 4 4 -9 15
|
||||||
|
29 102 44 102 6 0 9 4 6 8 -9 15 72 82 91 75 10 -4 14 -2 10 4 -4 6 12 17 36
|
||||||
|
27 26 10 43 12 45 6 4 -11 23 -14 21 -2 -3 19 2 25 11 12 5 -8 10 -10 10 -4z"/>
|
||||||
|
<path d="M616 1662 c-3 -5 1 -9 9 -9 8 0 12 4 9 9 -3 4 -7 8 -9 8 -2 0 -6 -4
|
||||||
|
-9 -8z"/>
|
||||||
|
<path d="M1306 1662 c-3 -5 1 -9 9 -9 8 0 12 4 9 9 -3 4 -7 8 -9 8 -2 0 -6 -4
|
||||||
|
-9 -8z"/>
|
||||||
|
<path d="M1830 1658 c0 -4 4 -8 9 -8 6 0 12 4 15 8 3 5 -1 9 -9 9 -8 0 -15 -4
|
||||||
|
-15 -9z"/>
|
||||||
|
<path d="M1753 1615 c0 -8 4 -12 9 -9 5 3 6 10 3 15 -9 13 -12 11 -12 -6z"/>
|
||||||
|
<path d="M1669 1523 c-13 -16 -12 -17 4 -4 9 7 17 15 17 17 0 8 -8 3 -21 -13z"/>
|
||||||
|
<path d="M2375 1440 c3 -5 8 -10 11 -10 2 0 4 5 4 10 0 6 -5 10 -11 10 -5 0
|
||||||
|
-7 -4 -4 -10z"/>
|
||||||
|
<path d="M2525 1440 c-3 -6 1 -7 9 -4 18 7 21 14 7 14 -6 0 -13 -4 -16 -10z"/>
|
||||||
|
<path d="M1667 1259 c7 -7 15 -10 18 -7 3 3 -2 9 -12 12 -14 6 -15 5 -6 -5z"/>
|
||||||
|
<path d="M2579 1208 c-5 -18 -6 -38 -1 -34 7 8 12 36 6 36 -2 0 -4 -1 -5 -2z"/>
|
||||||
|
<path d="M1353 1045 c0 -8 4 -12 9 -9 5 3 6 10 3 15 -9 13 -12 11 -12 -6z"/>
|
||||||
|
<path d="M1393 945 c0 -8 4 -12 9 -9 5 3 6 10 3 15 -9 13 -12 11 -12 -6z"/>
|
||||||
|
<path d="M2575 880 c-3 -5 -1 -10 4 -10 6 0 11 5 11 10 0 6 -2 10 -4 10 -3 0
|
||||||
|
-8 -4 -11 -10z"/>
|
||||||
|
<path d="M900 765 c0 -8 29 -12 39 -5 9 5 4 8 -13 8 -14 0 -26 -2 -26 -3z"/>
|
||||||
|
<path d="M2066 738 c3 -4 9 -8 15 -8 5 0 9 4 9 8 0 5 -7 9 -15 9 -8 0 -12 -4
|
||||||
|
-9 -9z"/>
|
||||||
|
<path d="M786 722 c-3 -5 1 -9 9 -9 8 0 12 4 9 9 -3 4 -7 8 -9 8 -2 0 -6 -4
|
||||||
|
-9 -8z"/>
|
||||||
|
<path d="M1076 718 c3 -5 10 -6 15 -3 13 9 11 12 -6 12 -8 0 -12 -4 -9 -9z"/>
|
||||||
|
<path d="M1190 726 c0 -2 7 -7 16 -10 8 -3 12 -2 9 4 -6 10 -25 14 -25 6z"/>
|
||||||
|
<path d="M1915 720 c-3 -5 -1 -10 4 -10 6 0 11 5 11 10 0 6 -2 10 -4 10 -3 0
|
||||||
|
-8 -4 -11 -10z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.2 KiB |
|
|
@ -14,7 +14,8 @@
|
||||||
manifest.json provides metadata used when your web app is installed on a
|
manifest.json provides metadata used when your web app is installed on a
|
||||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||||
-->
|
-->
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
<!-- <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> -->
|
||||||
|
<link rel="manifest" href="%PUBLIC_URL%/AdaptiveAgriculture/manifest.json" id="manifest-link" />
|
||||||
<!--
|
<!--
|
||||||
Notice the use of %PUBLIC_URL% in the tags above.
|
Notice the use of %PUBLIC_URL% in the tags above.
|
||||||
It will be replaced with the URL of the `public` folder during the build.
|
It will be replaced with the URL of the `public` folder during the build.
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,23 @@ import UserWrapper from './UserWrapper'
|
||||||
import { CssBaseline, Theme, ThemeProvider } from '@mui/material'
|
import { CssBaseline, Theme, ThemeProvider } from '@mui/material'
|
||||||
import { CreateTheme } from '../theme/theme'
|
import { CreateTheme } from '../theme/theme'
|
||||||
import { getThemeType, setThemeType } from '../theme/themeType'
|
import { getThemeType, setThemeType } from '../theme/themeType'
|
||||||
|
import { getWhitelabel } from 'services/whiteLabel'
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [token, setToken] = useState<string | undefined>(undefined)
|
const [token, setToken] = useState<string | undefined>(undefined)
|
||||||
const [palette, setPalette] = useState<Theme>(CreateTheme(getThemeType()));
|
const [palette, setPalette] = useState<Theme>(CreateTheme(getThemeType()));
|
||||||
|
|
||||||
|
const whiteLabel = getWhitelabel()
|
||||||
|
const manifestPath = whiteLabel.name.replace(/\s/g, "") + "/manifest.json"
|
||||||
|
// const defaultPath = "/AdaptiveAgriculture/manifest.json";
|
||||||
|
const manifestDocument = document.getElementById('manifest-link') as HTMLLinkElement
|
||||||
|
|
||||||
|
fetch(manifestPath).then(response => {
|
||||||
|
if (response.ok && manifestDocument) {
|
||||||
|
manifestDocument.href = manifestPath;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
let url: string | undefined = import.meta.env.VITE_AUTH0_CLIENT_DOMAIN;
|
let url: string | undefined = import.meta.env.VITE_AUTH0_CLIENT_DOMAIN;
|
||||||
let audience: string | undefined = import.meta.env.VITE_AUTH0_AUDIENCE;
|
let audience: string | undefined = import.meta.env.VITE_AUTH0_AUDIENCE;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,7 @@ export default function Devices() {
|
||||||
if (groupsLoading) return
|
if (groupsLoading) return
|
||||||
if (groups.length > 0) return
|
if (groups.length > 0) return
|
||||||
setGroupsLoading(true)
|
setGroupsLoading(true)
|
||||||
|
console.log("groups")
|
||||||
groupAPI.listGroups(
|
groupAPI.listGroups(
|
||||||
groupLimit,
|
groupLimit,
|
||||||
groupPage*groupLimit,
|
groupPage*groupLimit,
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ export const HTTPContext = createContext<IHTTPContext>({} as IHTTPContext);
|
||||||
|
|
||||||
export default function HTTPProvider(props: Props) {
|
export default function HTTPProvider(props: Props) {
|
||||||
const { children, token } = props;
|
const { children, token } = props;
|
||||||
const { isAuthenticated } = useAuth0();
|
const { isAuthenticated, /*loginWithRedirect,*/ loginWithPopup } = useAuth0();
|
||||||
|
|
||||||
const defaultOptions = (demo: boolean = false) => {
|
const defaultOptions = (demo: boolean = false) => {
|
||||||
if (demo || !isAuthenticated || !token) {
|
if (demo || !isAuthenticated || !token) {
|
||||||
|
|
@ -54,7 +54,36 @@ export default function HTTPProvider(props: Props) {
|
||||||
return config;
|
return config;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function isTokenExpired(token: string): boolean {
|
||||||
|
try {
|
||||||
|
// Split the token and decode the payload (second part)
|
||||||
|
const payloadBase64 = token.split('.')[1];
|
||||||
|
const decodedPayload = atob(payloadBase64); // Decode base64
|
||||||
|
const payload = JSON.parse(decodedPayload);
|
||||||
|
|
||||||
|
// Get expiration time (in seconds)
|
||||||
|
const exp = payload.exp;
|
||||||
|
|
||||||
|
if (!exp) return true; // No exp field? Treat as expired
|
||||||
|
|
||||||
|
// Current time in seconds
|
||||||
|
const now = Math.floor(Date.now() / 1000);
|
||||||
|
|
||||||
|
// Compare
|
||||||
|
return now >= exp;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Invalid token format:", error);
|
||||||
|
return true; // Err on the side of caution if decoding fails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function get<T>(url: string, spreadOptions?: AxiosRequestConfig): Promise<AxiosResponse<T>> {
|
function get<T>(url: string, spreadOptions?: AxiosRequestConfig): Promise<AxiosResponse<T>> {
|
||||||
|
if (isTokenExpired(token)) {
|
||||||
|
console.log("token expired")
|
||||||
|
loginWithPopup()
|
||||||
|
} else {
|
||||||
|
console.log("token is fine")
|
||||||
|
}
|
||||||
return axios.get(url, {...defaultOptions(), ...spreadOptions});
|
return axios.get(url, {...defaultOptions(), ...spreadOptions});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,20 @@
|
||||||
import { defineConfig } from 'vite'
|
import { defineConfig } from 'vite'
|
||||||
import react from '@vitejs/plugin-react'
|
import react from '@vitejs/plugin-react'
|
||||||
import tsconfigPaths from 'vite-tsconfig-paths'
|
import tsconfigPaths from 'vite-tsconfig-paths'
|
||||||
|
import { VitePWA } from 'vite-plugin-pwa';
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react(), tsconfigPaths()],
|
plugins: [
|
||||||
|
react(),
|
||||||
|
tsconfigPaths(),
|
||||||
|
VitePWA({
|
||||||
|
registerType: 'autoUpdate', // Automatically updates the service worker when a new version is available
|
||||||
|
workbox: {
|
||||||
|
globPatterns: ['**/*.{js,css,html,png,jpg,svg}'], // Cache all common asset types
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
build: {
|
build: {
|
||||||
outDir: './build',
|
outDir: './build',
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
|
|
|
||||||