Skip to content

Commit

Permalink
Copy src from old ui
Browse files Browse the repository at this point in the history
- copy src directory
- move public/index.html to index.html
- remove %PUBLIC_URL%
- add module script to the bottom of the body tag
  • Loading branch information
thienandangthanh committed Nov 7, 2023
1 parent 29b5010 commit 69b62f9
Show file tree
Hide file tree
Showing 14 changed files with 317 additions and 163 deletions.
24 changes: 18 additions & 6 deletions ui-vite/index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
<meta charset="utf-8" />
<link rel="shortcut icon" href="/static/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<link rel="manifest" href="/static/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>WiFi Connect</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
24 changes: 24 additions & 0 deletions ui-vite/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="%PUBLIC_URL%/static/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<link rel="manifest" href="%PUBLIC_URL%/static/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>WiFi Connect</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
Binary file added ui-vite/public/static/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions ui-vite/public/static/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"short_name": "WiFi Connect",
"name": "Easy WiFi setup for Linux devices from your mobile phone or laptop",
"icons": [
{
"src": "favicon.png",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
42 changes: 0 additions & 42 deletions ui-vite/src/App.css

This file was deleted.

35 changes: 0 additions & 35 deletions ui-vite/src/App.tsx

This file was deleted.

1 change: 0 additions & 1 deletion ui-vite/src/assets/react.svg

This file was deleted.

103 changes: 103 additions & 0 deletions ui-vite/src/components/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import React from 'react';
import logo from '../img/logo.svg';
import { Navbar, Provider, Container } from 'rendition';
import { NetworkInfoForm } from './NetworkInfoForm';
import { Notifications } from './Notifications';
import { createGlobalStyle } from 'styled-components';

const GlobalStyle = createGlobalStyle`
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
}
`;

export interface NetworkInfo {
ssid?: string;
identity?: string;
passphrase?: string;
}

export interface Network {
ssid: string;
security: string;
}

const App = () => {
const [attemptedConnect, setAttemptedConnect] = React.useState(false);
const [isFetchingNetworks, setIsFetchingNetworks] = React.useState(true);
const [error, setError] = React.useState('');
const [availableNetworks, setAvailableNetworks] = React.useState<Network[]>(
[],
);

React.useEffect(() => {
fetch('/networks')
.then((data) => {
if (data.status !== 200) {
throw new Error(data.statusText);
}

return data.json();
})
.then(setAvailableNetworks)
.catch((e: Error) => {
setError(`Failed to fetch available networks. ${e.message || e}`);
})
.finally(() => {
setIsFetchingNetworks(false);
});
}, []);

const onConnect = (data: NetworkInfo) => {
setAttemptedConnect(true);
setError('');

fetch('/connect', {
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json',
},
})
.then((resp) => {
if (resp.status !== 200) {
throw new Error(resp.statusText);
}
})
.catch((e: Error) => {
setError(`Failed to connect to the network. ${e.message || e}`);
});
};

return (
<Provider>
<GlobalStyle />
<Navbar brand={<img src={logo} style={{ height: 30 }} alt="logo" />} />

<Container>
<Notifications
attemptedConnect={attemptedConnect}
hasAvailableNetworks={
isFetchingNetworks || availableNetworks.length > 0
}
error={error}
/>
<NetworkInfoForm
availableNetworks={availableNetworks}
onSubmit={onConnect}
/>
</Container>
</Provider>
);
};

export default App;
110 changes: 110 additions & 0 deletions ui-vite/src/components/NetworkInfoForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { JSONSchema7 as JSONSchema } from 'json-schema';
import * as React from 'react';
import { Flex, Form, Heading, RenditionUiSchema } from 'rendition';
import { Network, NetworkInfo } from './App';

const getSchema = (availableNetworks: Network[]): JSONSchema => ({
type: 'object',
properties: {
ssid: {
title: 'SSID',
type: 'string',
default: availableNetworks[0]?.ssid,
oneOf: availableNetworks.map((network) => ({
const: network.ssid,
title: network.ssid,
})),
},
identity: {
title: 'User',
type: 'string',
default: '',
},
passphrase: {
title: 'Passphrase',
type: 'string',
default: '',
},
},
required: ['ssid'],
});

const getUiSchema = (isEnterprise: boolean): RenditionUiSchema => ({
ssid: {
'ui:placeholder': 'Select SSID',
'ui:options': {
emphasized: true,
},
},
identity: {
'ui:options': {
emphasized: true,
},
'ui:widget': !isEnterprise ? 'hidden' : undefined,
},
passphrase: {
'ui:widget': 'password',
'ui:options': {
emphasized: true,
},
},
});

const isEnterpriseNetwork = (
networks: Network[],
selectedNetworkSsid?: string,
) => {
return networks.some(
(network) =>
network.ssid === selectedNetworkSsid && network.security === 'enterprise',
);
};

interface NetworkInfoFormProps {
availableNetworks: Network[];
onSubmit: (data: NetworkInfo) => void;
}

export const NetworkInfoForm = ({
availableNetworks,
onSubmit,
}: NetworkInfoFormProps) => {
const [data, setData] = React.useState<NetworkInfo>({});

const isSelectedNetworkEnterprise = isEnterpriseNetwork(
availableNetworks,
data.ssid,
);

return (
<Flex
flexDirection="column"
alignItems="center"
justifyContent="center"
m={4}
mt={5}
>
<Heading.h3 align="center" mb={4}>
Hi! Please choose your WiFi from the list
</Heading.h3>

<Form
width={['100%', '80%', '60%', '40%']}
onFormChange={({ formData }) => {
setData(formData);
}}
onFormSubmit={({ formData }) => onSubmit(formData)}
value={data}
schema={getSchema(availableNetworks)}
uiSchema={getUiSchema(isSelectedNetworkEnterprise)}
submitButtonProps={{
width: '60%',
mx: '20%',
mt: 3,
disabled: availableNetworks.length <= 0,
}}
submitButtonText={'Connect'}
/>
</Flex>
);
};
Loading

0 comments on commit 69b62f9

Please sign in to comment.