feat: add "apps/front" with basic dashboard mockup
This commit is contained in:
parent
598fef10b7
commit
3c3d76c33c
13
apps/front/.eslintignore
Normal file
13
apps/front/.eslintignore
Normal file
@ -0,0 +1,13 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/build
|
||||
/.svelte-kit
|
||||
/package
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# Ignore files for PNPM, NPM and YARN
|
||||
pnpm-lock.yaml
|
||||
package-lock.json
|
||||
yarn.lock
|
31
apps/front/.eslintrc.cjs
Normal file
31
apps/front/.eslintrc.cjs
Normal file
@ -0,0 +1,31 @@
|
||||
/** @type { import("eslint").Linter.Config } */
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:svelte/recommended',
|
||||
'prettier'
|
||||
],
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['@typescript-eslint'],
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
ecmaVersion: 2020,
|
||||
extraFileExtensions: ['.svelte']
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
es2017: true,
|
||||
node: true
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.svelte'],
|
||||
parser: 'svelte-eslint-parser',
|
||||
parserOptions: {
|
||||
parser: '@typescript-eslint/parser'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
10
apps/front/.gitignore
vendored
Normal file
10
apps/front/.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/build
|
||||
/.svelte-kit
|
||||
/package
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
1
apps/front/.npmrc
Normal file
1
apps/front/.npmrc
Normal file
@ -0,0 +1 @@
|
||||
engine-strict=true
|
4
apps/front/.prettierignore
Normal file
4
apps/front/.prettierignore
Normal file
@ -0,0 +1,4 @@
|
||||
# Ignore files for PNPM, NPM and YARN
|
||||
pnpm-lock.yaml
|
||||
package-lock.json
|
||||
yarn.lock
|
8
apps/front/.prettierrc
Normal file
8
apps/front/.prettierrc
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"useTabs": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"printWidth": 100,
|
||||
"plugins": ["prettier-plugin-svelte"],
|
||||
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
||||
}
|
38
apps/front/README.md
Normal file
38
apps/front/README.md
Normal file
@ -0,0 +1,38 @@
|
||||
# create-svelte
|
||||
|
||||
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/main/packages/create-svelte).
|
||||
|
||||
## Creating a project
|
||||
|
||||
If you're seeing this, you've probably already done this step. Congrats!
|
||||
|
||||
```bash
|
||||
# create a new project in the current directory
|
||||
npm create svelte@latest
|
||||
|
||||
# create a new project in my-app
|
||||
npm create svelte@latest my-app
|
||||
```
|
||||
|
||||
## Developing
|
||||
|
||||
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
|
||||
# or start the server and open the app in a new browser tab
|
||||
npm run dev -- --open
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
To create a production version of your app:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
You can preview the production build with `npm run preview`.
|
||||
|
||||
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.
|
41
apps/front/package.json
Normal file
41
apps/front/package.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "gb-lux-sveltekit",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"test": "vitest",
|
||||
"lint": "prettier --check . && eslint .",
|
||||
"format": "prettier --write ."
|
||||
},
|
||||
"dependencies": {
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "^3.0.0",
|
||||
"@sveltejs/kit": "^2.0.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
||||
"@tailwindcss/forms": "^0.5.7",
|
||||
"@types/eslint": "8.56.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
||||
"@typescript-eslint/parser": "^6.0.0",
|
||||
"autoprefixer": "^10.4.17",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-svelte": "^2.35.1",
|
||||
"postcss": "^8.4.33",
|
||||
"prettier": "^3.1.1",
|
||||
"prettier-plugin-svelte": "^3.1.2",
|
||||
"svelte": "^4.2.7",
|
||||
"svelte-check": "^3.6.0",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"tslib": "^2.4.1",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^5.0.3",
|
||||
"vitest": "^1.2.0"
|
||||
}
|
||||
}
|
2909
apps/front/pnpm-lock.yaml
generated
Normal file
2909
apps/front/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
6
apps/front/postcss.config.js
Normal file
6
apps/front/postcss.config.js
Normal file
@ -0,0 +1,6 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
3
apps/front/src/app.css
Normal file
3
apps/front/src/app.css
Normal file
@ -0,0 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
13
apps/front/src/app.d.ts
vendored
Normal file
13
apps/front/src/app.d.ts
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
// See https://kit.svelte.dev/docs/types#app
|
||||
// for information about these interfaces
|
||||
declare global {
|
||||
namespace App {
|
||||
// interface Error {}
|
||||
// interface Locals {}
|
||||
// interface PageData {}
|
||||
// interface PageState {}
|
||||
// interface Platform {}
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
12
apps/front/src/app.html
Normal file
12
apps/front/src/app.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!doctype html>
|
||||
<html lang="en" class="h-full bg-gray-50">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover" class="h-full">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
7
apps/front/src/index.test.ts
Normal file
7
apps/front/src/index.test.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
|
||||
describe('sum test', () => {
|
||||
it('adds 1 + 2 to equal 3', () => {
|
||||
expect(1 + 2).toBe(3);
|
||||
});
|
||||
});
|
41
apps/front/src/lib/client/components/login.svelte
Normal file
41
apps/front/src/lib/client/components/login.svelte
Normal file
@ -0,0 +1,41 @@
|
||||
<script lang="ts">
|
||||
import { auth } from '$lib/client/stores/auth';
|
||||
</script>
|
||||
|
||||
<div class="flex min-h-full flex-col justify-center py-12 sm:px-6 lg:px-8">
|
||||
<div class="sm:mx-auto sm:w-full sm:max-w-md">
|
||||
<img class="mx-auto h-10 w-auto" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=600" alt="Your Company">
|
||||
<h2 class="mt-6 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900">Sign in to your account</h2>
|
||||
</div>
|
||||
|
||||
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-[480px]">
|
||||
<div class="bg-white px-6 py-12 shadow sm:rounded-lg sm:px-12">
|
||||
<form class="space-y-6" on:submit|preventDefault={auth.signIn}>
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-medium leading-6 text-gray-900">Organisation</label>
|
||||
<div class="mt-2">
|
||||
<input id="organisation" name="organisation" type="text" autocomplete="email" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-medium leading-6 text-gray-900">Login</label>
|
||||
<div class="mt-2">
|
||||
<input id="login" name="login" type="text" autocomplete="email" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="password" class="block text-sm font-medium leading-6 text-gray-900">Password</label>
|
||||
<div class="mt-2">
|
||||
<input id="password" name="password" type="password" autocomplete="current-password" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button type="submit" class="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Sign in</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
4
apps/front/src/lib/client/components/map.svelte
Normal file
4
apps/front/src/lib/client/components/map.svelte
Normal file
@ -0,0 +1,4 @@
|
||||
<script lang="ts">
|
||||
</script>
|
||||
|
||||
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3680.0713312310418!2d103.86541329291512!3d1.2815590836801172!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x31da1904937e1633%3A0x62099677b59fca76!2sGardens%20by%20the%20Bay!5e0!3m2!1sen!2ssg!4v1706174691015!5m2!1sen!2ssg" width="100%" height="450" style="border:0;" allowfullscreen="" loading="lazy" referrerpolicy="no-referrer-when-downgrade"></iframe>
|
65
apps/front/src/lib/client/components/table.svelte
Normal file
65
apps/front/src/lib/client/components/table.svelte
Normal file
@ -0,0 +1,65 @@
|
||||
<script lang="ts">
|
||||
export let title = 'Failed devices';
|
||||
export let description = 'Lamp is not working / too much voltage / no signal from device for a long time.'
|
||||
export let link = '#';
|
||||
export let addLink = ''
|
||||
export let deleteLink = ''
|
||||
</script>
|
||||
|
||||
<div class="">
|
||||
<div class="mt-10 sm:flex sm:items-center">
|
||||
<div class="sm:flex-auto">
|
||||
<h1 class="text-base font-semibold leading-6 text-gray-900">{title}</h1>
|
||||
<p class="mt-2 text-sm text-gray-700">{description}</p>
|
||||
</div>
|
||||
{#if addLink}
|
||||
<div class="mt-4 sm:ml-16 sm:mt-0 sm:flex-none">
|
||||
<a href={addLink} class="flex gap-1 items-center rounded-md bg-indigo-600 px-3 py-2 text-center text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
|
||||
</svg>
|
||||
Add
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="mt-8 flow-root">
|
||||
<div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
|
||||
<div class="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
|
||||
<div class="overflow-hidden shadow ring-1 ring-black ring-opacity-5 sm:rounded-lg">
|
||||
<table class="min-w-full divide-y divide-gray-300">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Name</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">Title</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">Email</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">Role</th>
|
||||
<th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6">
|
||||
<span class="sr-only">Edit</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200 bg-white">
|
||||
{#each {length: 10} as item}
|
||||
<tr>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6">Lindsay Walton</td>
|
||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">Front-end Developer</td>
|
||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">lindsay.walton@example.com</td>
|
||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">Member</td>
|
||||
<td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6">
|
||||
<a href={link} class="text-indigo-600 hover:text-indigo-900">Edit<span class="sr-only">, Lindsay Walton</span></a>
|
||||
{#if deleteLink}
|
||||
<button type="button" class="ml-2 text-red-600 hover:text-red-900">
|
||||
Delete
|
||||
</button>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
29
apps/front/src/lib/client/stores/auth.ts
Normal file
29
apps/front/src/lib/client/stores/auth.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
interface Store {
|
||||
isSignedIn: boolean;
|
||||
}
|
||||
|
||||
const store = writable<Store>({
|
||||
isSignedIn: true
|
||||
});
|
||||
|
||||
export const auth = {
|
||||
subscribe: store.subscribe,
|
||||
signIn: () => {
|
||||
store.update((store) => {
|
||||
return {
|
||||
...store,
|
||||
isSignedIn: true
|
||||
};
|
||||
});
|
||||
},
|
||||
signOut: () => {
|
||||
store.update((store) => {
|
||||
return {
|
||||
...store,
|
||||
isSignedIn: false
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
1
apps/front/src/lib/index.ts
Normal file
1
apps/front/src/lib/index.ts
Normal file
@ -0,0 +1 @@
|
||||
// place files you want to import through the `$lib` alias in this folder.
|
339
apps/front/src/routes/+layout.svelte
Normal file
339
apps/front/src/routes/+layout.svelte
Normal file
@ -0,0 +1,339 @@
|
||||
<script lang="ts">
|
||||
import "../app.css";
|
||||
import Login from '$lib/client/components/Login.svelte';
|
||||
import { auth } from '$lib/client/stores/auth';
|
||||
</script>
|
||||
|
||||
{#if $auth.isSignedIn}
|
||||
|
||||
|
||||
<!--
|
||||
This example requires some changes to your config:
|
||||
|
||||
```
|
||||
// tailwind.config.js
|
||||
module.exports = {
|
||||
// ...
|
||||
plugins: [
|
||||
// ...
|
||||
require('@tailwindcss/forms'),
|
||||
],
|
||||
}
|
||||
```
|
||||
-->
|
||||
<!--
|
||||
This example requires updating your template:
|
||||
|
||||
```
|
||||
<html class="h-full bg-white">
|
||||
<body class="h-full">
|
||||
```
|
||||
-->
|
||||
<div>
|
||||
<!-- Off-canvas menu for mobile, show/hide based on off-canvas menu state. -->
|
||||
<div class="relative z-50 lg:hidden" role="dialog" aria-modal="true">
|
||||
<!--
|
||||
Off-canvas menu backdrop, show/hide based on off-canvas menu state.
|
||||
|
||||
Entering: "transition-opacity ease-linear duration-300"
|
||||
From: "opacity-0"
|
||||
To: "opacity-100"
|
||||
Leaving: "transition-opacity ease-linear duration-300"
|
||||
From: "opacity-100"
|
||||
To: "opacity-0"
|
||||
-->
|
||||
<div class="fixed inset-0 bg-gray-900/80"></div>
|
||||
|
||||
<div class="fixed inset-0 flex">
|
||||
<!--
|
||||
Off-canvas menu, show/hide based on off-canvas menu state.
|
||||
|
||||
Entering: "transition ease-in-out duration-300 transform"
|
||||
From: "-translate-x-full"
|
||||
To: "translate-x-0"
|
||||
Leaving: "transition ease-in-out duration-300 transform"
|
||||
From: "translate-x-0"
|
||||
To: "-translate-x-full"
|
||||
-->
|
||||
<div class="relative mr-16 flex w-full max-w-xs flex-1">
|
||||
<!--
|
||||
Close button, show/hide based on off-canvas menu state.
|
||||
|
||||
Entering: "ease-in-out duration-300"
|
||||
From: "opacity-0"
|
||||
To: "opacity-100"
|
||||
Leaving: "ease-in-out duration-300"
|
||||
From: "opacity-100"
|
||||
To: "opacity-0"
|
||||
-->
|
||||
<div class="absolute left-full top-0 flex w-16 justify-center pt-5">
|
||||
<button type="button" class="-m-2.5 p-2.5">
|
||||
<span class="sr-only">Close sidebar</span>
|
||||
<svg class="h-6 w-6 text-white" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Sidebar component, swap this element with another sidebar if you like -->
|
||||
<div class="flex grow flex-col gap-y-5 overflow-y-auto bg-gray-900 px-6 pb-4 ring-1 ring-white/10">
|
||||
<div class="flex h-16 shrink-0 items-center">
|
||||
<img class="h-8 w-auto" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=500" alt="Your Company">
|
||||
</div>
|
||||
<nav class="flex flex-1 flex-col">
|
||||
<ul role="list" class="flex flex-1 flex-col gap-y-7">
|
||||
<li>
|
||||
<ul role="list" class="-mx-2 space-y-1">
|
||||
<li>
|
||||
<!-- Current: "bg-gray-800 text-white", Default: "text-gray-400 hover:text-white hover:bg-gray-800" -->
|
||||
<a href="#" class="bg-gray-800 text-white group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
|
||||
<svg class="h-6 w-6 shrink-0" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" />
|
||||
</svg>
|
||||
Dashboard
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="text-gray-400 hover:text-white hover:bg-gray-800 group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
|
||||
<svg class="h-6 w-6 shrink-0" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 19.128a9.38 9.38 0 002.625.372 9.337 9.337 0 004.121-.952 4.125 4.125 0 00-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 018.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0111.964-3.07M12 6.375a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zm8.25 2.25a2.625 2.625 0 11-5.25 0 2.625 2.625 0 015.25 0z" />
|
||||
</svg>
|
||||
Team
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="text-gray-400 hover:text-white hover:bg-gray-800 group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
|
||||
<svg class="h-6 w-6 shrink-0" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12.75V12A2.25 2.25 0 014.5 9.75h15A2.25 2.25 0 0121.75 12v.75m-8.69-6.44l-2.12-2.12a1.5 1.5 0 00-1.061-.44H4.5A2.25 2.25 0 002.25 6v12a2.25 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9a2.25 2.25 0 00-2.25-2.25h-5.379a1.5 1.5 0 01-1.06-.44z" />
|
||||
</svg>
|
||||
Projects
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="text-gray-400 hover:text-white hover:bg-gray-800 group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
|
||||
<svg class="h-6 w-6 shrink-0" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 012.25-2.25h13.5A2.25 2.25 0 0121 7.5v11.25m-18 0A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75m-18 0v-7.5A2.25 2.25 0 015.25 9h13.5A2.25 2.25 0 0121 11.25v7.5" />
|
||||
</svg>
|
||||
Calendar
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="text-gray-400 hover:text-white hover:bg-gray-800 group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
|
||||
<svg class="h-6 w-6 shrink-0" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 01-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 011.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 00-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 01-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 00-3.375-3.375h-1.5a1.125 1.125 0 01-1.125-1.125v-1.5a3.375 3.375 0 00-3.375-3.375H9.75" />
|
||||
</svg>
|
||||
Documents
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="text-gray-400 hover:text-white hover:bg-gray-800 group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
|
||||
<svg class="h-6 w-6 shrink-0" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 6a7.5 7.5 0 107.5 7.5h-7.5V6z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 10.5H21A7.5 7.5 0 0013.5 3v7.5z" />
|
||||
</svg>
|
||||
Reports
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<div class="text-xs font-semibold leading-6 text-gray-400">Your teams</div>
|
||||
<ul role="list" class="-mx-2 mt-2 space-y-1">
|
||||
<li>
|
||||
<!-- Current: "bg-gray-800 text-white", Default: "text-gray-400 hover:text-white hover:bg-gray-800" -->
|
||||
<a href="#" class="text-gray-400 hover:text-white hover:bg-gray-800 group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
|
||||
<span class="flex h-6 w-6 shrink-0 items-center justify-center rounded-lg border border-gray-700 bg-gray-800 text-[0.625rem] font-medium text-gray-400 group-hover:text-white">H</span>
|
||||
<span class="truncate">Heroicons</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="text-gray-400 hover:text-white hover:bg-gray-800 group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
|
||||
<span class="flex h-6 w-6 shrink-0 items-center justify-center rounded-lg border border-gray-700 bg-gray-800 text-[0.625rem] font-medium text-gray-400 group-hover:text-white">T</span>
|
||||
<span class="truncate">Tailwind Labs</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="text-gray-400 hover:text-white hover:bg-gray-800 group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
|
||||
<span class="flex h-6 w-6 shrink-0 items-center justify-center rounded-lg border border-gray-700 bg-gray-800 text-[0.625rem] font-medium text-gray-400 group-hover:text-white">W</span>
|
||||
<span class="truncate">Workcation</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="mt-auto">
|
||||
<a href="#" class="group -mx-2 flex gap-x-3 rounded-md p-2 text-sm font-semibold leading-6 text-gray-400 hover:bg-gray-800 hover:text-white">
|
||||
<svg class="h-6 w-6 shrink-0" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
Settings
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Static sidebar for desktop -->
|
||||
<div class="hidden lg:fixed lg:inset-y-0 lg:z-50 lg:flex lg:w-72 lg:flex-col">
|
||||
<!-- Sidebar component, swap this element with another sidebar if you like -->
|
||||
<div class="flex grow flex-col gap-y-5 overflow-y-auto bg-gray-900 px-6 pb-4">
|
||||
<div class="flex h-16 shrink-0 items-center">
|
||||
<img class="h-8 w-auto" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=500" alt="Your Company">
|
||||
</div>
|
||||
<nav class="flex flex-1 flex-col">
|
||||
<ul role="list" class="flex flex-1 flex-col gap-y-7">
|
||||
<li>
|
||||
<ul role="list" class="-mx-2 space-y-1">
|
||||
<li>
|
||||
<!-- Current: "bg-gray-800 text-white", Default: "text-gray-400 hover:text-white hover:bg-gray-800" -->
|
||||
<a href="/" class="bg-gray-800 text-white group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
|
||||
<svg class="h-6 w-6 shrink-0" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" />
|
||||
</svg>
|
||||
Dashboard
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/map" class="text-gray-400 hover:text-white hover:bg-gray-800 group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9 20l-5.447-2.724A1 1 0 013 16.382V5.618a1 1 0 011.447-.894L9 7m0 13l6-3m-6 3V7m6 10l4.553 2.276A1 1 0 0021 18.382V7.618a1 1 0 00-.553-.894L15 4m0 13V4m0 0L9 7" />
|
||||
</svg>
|
||||
Map
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/device-groups" class="text-gray-400 hover:text-white hover:bg-gray-800 group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
|
||||
</svg>
|
||||
Device Groups
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="text-gray-400 hover:text-white hover:bg-gray-800 group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
|
||||
</svg>
|
||||
Export Data
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="text-gray-400 hover:text-white hover:bg-gray-800 group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
|
||||
</svg>
|
||||
Notifications
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="text-gray-400 hover:text-white hover:bg-gray-800 group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />
|
||||
</svg>
|
||||
Admin
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="text-gray-400 hover:text-white hover:bg-gray-800 group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
|
||||
<svg class="h-6 w-6 shrink-0" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 6a7.5 7.5 0 107.5 7.5h-7.5V6z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 10.5H21A7.5 7.5 0 0013.5 3v7.5z" />
|
||||
</svg>
|
||||
Reports
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="mt-auto">
|
||||
<a href="#" class="group -mx-2 flex gap-x-3 rounded-md p-2 text-sm font-semibold leading-6 text-gray-400 hover:bg-gray-800 hover:text-white">
|
||||
<svg class="h-6 w-6 shrink-0" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
Settings
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="lg:pl-72">
|
||||
<div class="sticky top-0 z-40 flex h-16 shrink-0 items-center gap-x-4 border-b border-gray-200 bg-white px-4 shadow-sm sm:gap-x-6 sm:px-6 lg:px-8">
|
||||
<button type="button" class="-m-2.5 p-2.5 text-gray-700 lg:hidden">
|
||||
<span class="sr-only">Open sidebar</span>
|
||||
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<!-- Separator -->
|
||||
<div class="h-6 w-px bg-gray-900/10 lg:hidden" aria-hidden="true"></div>
|
||||
|
||||
<div class="flex flex-1 gap-x-4 self-stretch lg:gap-x-6">
|
||||
<form class="relative flex flex-1" action="#" method="GET">
|
||||
<label for="search-field" class="sr-only">Search</label>
|
||||
<svg class="pointer-events-none absolute inset-y-0 left-0 h-full w-5 text-gray-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M9 3.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM2 9a7 7 0 1112.452 4.391l3.328 3.329a.75.75 0 11-1.06 1.06l-3.329-3.328A7 7 0 012 9z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
<input id="search-field" class="block h-full w-full border-0 py-0 pl-8 pr-0 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm" placeholder="Search..." type="search" name="search">
|
||||
</form>
|
||||
<div class="flex items-center gap-x-4 lg:gap-x-6">
|
||||
<button type="button" class="-m-2.5 p-2.5 text-gray-400 hover:text-gray-500">
|
||||
<span class="sr-only">View notifications</span>
|
||||
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<!-- Separator -->
|
||||
<div class="hidden lg:block lg:h-6 lg:w-px lg:bg-gray-900/10" aria-hidden="true"></div>
|
||||
|
||||
<!-- Profile dropdown -->
|
||||
<div class="relative">
|
||||
<button type="button" class="-m-1.5 flex items-center p-1.5" id="user-menu-button" aria-expanded="false" aria-haspopup="true">
|
||||
<span class="sr-only">Open user menu</span>
|
||||
<img class="h-8 w-8 rounded-full bg-gray-50" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="">
|
||||
<span class="hidden lg:flex lg:items-center">
|
||||
<span class="ml-4 text-sm font-semibold leading-6 text-gray-900" aria-hidden="true">Tom Cook</span>
|
||||
<svg class="ml-2 h-5 w-5 text-gray-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<!--
|
||||
Dropdown menu, show/hide based on menu state.
|
||||
|
||||
Entering: "transition ease-out duration-100"
|
||||
From: "transform opacity-0 scale-95"
|
||||
To: "transform opacity-100 scale-100"
|
||||
Leaving: "transition ease-in duration-75"
|
||||
From: "transform opacity-100 scale-100"
|
||||
To: "transform opacity-0 scale-95"
|
||||
-->
|
||||
<div class="absolute right-0 z-10 mt-2.5 w-32 origin-top-right rounded-md bg-white py-2 shadow-lg ring-1 ring-gray-900/5 focus:outline-none" role="menu" aria-orientation="vertical" aria-labelledby="user-menu-button" tabindex="-1">
|
||||
<!-- Active: "bg-gray-50", Not Active: "" -->
|
||||
<a href="#" class="block px-3 py-1 text-sm leading-6 text-gray-900" role="menuitem" tabindex="-1" id="user-menu-item-0">Your profile</a>
|
||||
<button on:click={auth.signOut} class="block px-3 py-1 text-sm leading-6 text-gray-900" role="menuitem" tabindex="-1" id="user-menu-item-1">Sign out</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<main class="py-10">
|
||||
<div class="px-4 sm:px-6 lg:px-8">
|
||||
<!-- Your content -->
|
||||
<slot />
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<Login/>
|
||||
{/if}
|
41
apps/front/src/routes/+page.svelte
Normal file
41
apps/front/src/routes/+page.svelte
Normal file
@ -0,0 +1,41 @@
|
||||
<script lang="ts">
|
||||
import Table from '$lib/client/components/table.svelte';
|
||||
</script>
|
||||
|
||||
<!-- Pinned projects -->
|
||||
<div class="">
|
||||
<ul role="list" class="mt-3 grid grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-6 xl:grid-cols-4">
|
||||
<li class="relative col-span-1 flex rounded-md shadow-sm">
|
||||
<div class="flex w-16 flex-shrink-0 items-center justify-center bg-green-500 rounded-l-md text-sm font-medium text-white">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="flex flex-1 items-center justify-between truncate rounded-r-md border-b border-r border-t border-gray-200 bg-white">
|
||||
<div class="flex-1 truncate px-4 py-2 text-sm">
|
||||
<a href="#" class="font-medium text-gray-900 hover:text-gray-600">Total devices</a>
|
||||
<p class="text-gray-500">863</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="relative col-span-1 flex rounded-md shadow-sm">
|
||||
<div class="flex w-16 flex-shrink-0 items-center justify-center bg-pink-600 rounded-l-md text-sm font-medium text-white">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="flex flex-1 items-center justify-between truncate rounded-r-md border-b border-r border-t border-gray-200 bg-white">
|
||||
<div class="flex-1 truncate px-4 py-2 text-sm">
|
||||
<a href="#" class="font-medium text-gray-900 hover:text-gray-600">Failed lamps</a>
|
||||
<p class="text-gray-500">12 items</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="mt-10">
|
||||
<Table/>
|
||||
</div>
|
5
apps/front/src/routes/device-groups/+page.svelte
Normal file
5
apps/front/src/routes/device-groups/+page.svelte
Normal file
@ -0,0 +1,5 @@
|
||||
<script lang="ts">
|
||||
import Table from '$lib/client/components/table.svelte';
|
||||
</script>
|
||||
|
||||
<Table title="All groups" description="Here you can manage schedules, add/remove devices." link="/device-groups/1"/>
|
31
apps/front/src/routes/device-groups/[id]/+page.svelte
Normal file
31
apps/front/src/routes/device-groups/[id]/+page.svelte
Normal file
@ -0,0 +1,31 @@
|
||||
<script lang="ts">
|
||||
import Table from '$lib/client/components/table.svelte';
|
||||
</script>
|
||||
|
||||
<div class="sm:col-span-4 flex gap-2 items-center">
|
||||
<label for="website" class="block text-sm font-medium leading-6 text-gray-900">Zone ID:</label>
|
||||
<div class="flex rounded-md shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-inset focus-within:ring-indigo-600 sm:max-w-md">
|
||||
<input type="text" name="website" id="website" class="block flex-1 border-0 bg-transparent py-1.5 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6" placeholder="zone-001">
|
||||
</div>
|
||||
<button
|
||||
class="inline-flex items-center justify-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<Table
|
||||
addLink="/device-groups/1/add"
|
||||
deleteLink="/device-groups/1/delete"
|
||||
description="List of devices in group #001"
|
||||
title="Devices in group #001"
|
||||
/>
|
||||
|
||||
<div class="mt-10">
|
||||
<Table
|
||||
addLink="/device-groups/1/add"
|
||||
deleteLink="/device-groups/1/delete"
|
||||
description="When to turn on/off devices"
|
||||
title="Schedules"
|
||||
/>
|
||||
</div>
|
212
apps/front/src/routes/device-groups/[id]/add/+page.svelte
Normal file
212
apps/front/src/routes/device-groups/[id]/add/+page.svelte
Normal file
@ -0,0 +1,212 @@
|
||||
|
||||
<div class="space-y-10 divide-y divide-gray-900/10">
|
||||
<h1 class="text-4xl leading-7 text-gray-900">Add a device</h1>
|
||||
<div class="grid grid-cols-1 gap-x-8 gap-y-8 md:grid-cols-3">
|
||||
<div class="px-4 sm:px-0">
|
||||
<h2 class="text-base font-semibold leading-7 text-gray-900">Profile</h2>
|
||||
<p class="mt-1 text-sm leading-6 text-gray-600">This information will be displayed publicly so be careful what you share.</p>
|
||||
</div>
|
||||
|
||||
<form class="bg-white shadow-sm ring-1 ring-gray-900/5 sm:rounded-xl md:col-span-2">
|
||||
<div class="px-4 py-6 sm:p-8">
|
||||
<div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
|
||||
<div class="sm:col-span-4">
|
||||
<label for="website" class="block text-sm font-medium leading-6 text-gray-900">Website</label>
|
||||
<div class="mt-2">
|
||||
<div class="flex rounded-md shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-inset focus-within:ring-indigo-600 sm:max-w-md">
|
||||
<span class="flex select-none items-center pl-3 text-gray-500 sm:text-sm">http://</span>
|
||||
<input type="text" name="website" id="website" class="block flex-1 border-0 bg-transparent py-1.5 pl-1 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6" placeholder="www.example.com">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-full">
|
||||
<label for="about" class="block text-sm font-medium leading-6 text-gray-900">About</label>
|
||||
<div class="mt-2">
|
||||
<textarea id="about" name="about" rows="3" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"></textarea>
|
||||
</div>
|
||||
<p class="mt-3 text-sm leading-6 text-gray-600">Write a few sentences about yourself.</p>
|
||||
</div>
|
||||
|
||||
<div class="col-span-full">
|
||||
<label for="photo" class="block text-sm font-medium leading-6 text-gray-900">Photo</label>
|
||||
<div class="mt-2 flex items-center gap-x-3">
|
||||
<svg class="h-12 w-12 text-gray-300" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M18.685 19.097A9.723 9.723 0 0021.75 12c0-5.385-4.365-9.75-9.75-9.75S2.25 6.615 2.25 12a9.723 9.723 0 003.065 7.097A9.716 9.716 0 0012 21.75a9.716 9.716 0 006.685-2.653zm-12.54-1.285A7.486 7.486 0 0112 15a7.486 7.486 0 015.855 2.812A8.224 8.224 0 0112 20.25a8.224 8.224 0 01-5.855-2.438zM15.75 9a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
<button type="button" class="rounded-md bg-white px-2.5 py-1.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50">Change</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-full">
|
||||
<label for="cover-photo" class="block text-sm font-medium leading-6 text-gray-900">Cover photo</label>
|
||||
<div class="mt-2 flex justify-center rounded-lg border border-dashed border-gray-900/25 px-6 py-10">
|
||||
<div class="text-center">
|
||||
<svg class="mx-auto h-12 w-12 text-gray-300" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M1.5 6a2.25 2.25 0 012.25-2.25h16.5A2.25 2.25 0 0122.5 6v12a2.25 2.25 0 01-2.25 2.25H3.75A2.25 2.25 0 011.5 18V6zM3 16.06V18c0 .414.336.75.75.75h16.5A.75.75 0 0021 18v-1.94l-2.69-2.689a1.5 1.5 0 00-2.12 0l-.88.879.97.97a.75.75 0 11-1.06 1.06l-5.16-5.159a1.5 1.5 0 00-2.12 0L3 16.061zm10.125-7.81a1.125 1.125 0 112.25 0 1.125 1.125 0 01-2.25 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
<div class="mt-4 flex text-sm leading-6 text-gray-600">
|
||||
<label for="file-upload" class="relative cursor-pointer rounded-md bg-white font-semibold text-indigo-600 focus-within:outline-none focus-within:ring-2 focus-within:ring-indigo-600 focus-within:ring-offset-2 hover:text-indigo-500">
|
||||
<span>Upload a file</span>
|
||||
<input id="file-upload" name="file-upload" type="file" class="sr-only">
|
||||
</label>
|
||||
<p class="pl-1">or drag and drop</p>
|
||||
</div>
|
||||
<p class="text-xs leading-5 text-gray-600">PNG, JPG, GIF up to 10MB</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-end gap-x-6 border-t border-gray-900/10 px-4 py-4 sm:px-8">
|
||||
<button type="button" class="text-sm font-semibold leading-6 text-gray-900">Cancel</button>
|
||||
<button type="submit" class="rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 gap-x-8 gap-y-8 pt-10 md:grid-cols-3">
|
||||
<div class="px-4 sm:px-0">
|
||||
<h2 class="text-base font-semibold leading-7 text-gray-900">Personal Information</h2>
|
||||
<p class="mt-1 text-sm leading-6 text-gray-600">Use a permanent address where you can receive mail.</p>
|
||||
</div>
|
||||
|
||||
<form class="bg-white shadow-sm ring-1 ring-gray-900/5 sm:rounded-xl md:col-span-2">
|
||||
<div class="px-4 py-6 sm:p-8">
|
||||
<div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
|
||||
<div class="sm:col-span-3">
|
||||
<label for="first-name" class="block text-sm font-medium leading-6 text-gray-900">First name</label>
|
||||
<div class="mt-2">
|
||||
<input type="text" name="first-name" id="first-name" autocomplete="given-name" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sm:col-span-3">
|
||||
<label for="last-name" class="block text-sm font-medium leading-6 text-gray-900">Last name</label>
|
||||
<div class="mt-2">
|
||||
<input type="text" name="last-name" id="last-name" autocomplete="family-name" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sm:col-span-4">
|
||||
<label for="email" class="block text-sm font-medium leading-6 text-gray-900">Email address</label>
|
||||
<div class="mt-2">
|
||||
<input id="email" name="email" type="email" autocomplete="email" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sm:col-span-4">
|
||||
<label for="country" class="block text-sm font-medium leading-6 text-gray-900">Country</label>
|
||||
<div class="mt-2">
|
||||
<select id="country" name="country" autocomplete="country-name" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:max-w-xs sm:text-sm sm:leading-6">
|
||||
<option>United States</option>
|
||||
<option>Canada</option>
|
||||
<option>Mexico</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-full">
|
||||
<label for="street-address" class="block text-sm font-medium leading-6 text-gray-900">Street address</label>
|
||||
<div class="mt-2">
|
||||
<input type="text" name="street-address" id="street-address" autocomplete="street-address" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sm:col-span-2 sm:col-start-1">
|
||||
<label for="city" class="block text-sm font-medium leading-6 text-gray-900">City</label>
|
||||
<div class="mt-2">
|
||||
<input type="text" name="city" id="city" autocomplete="address-level2" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sm:col-span-2">
|
||||
<label for="region" class="block text-sm font-medium leading-6 text-gray-900">State / Province</label>
|
||||
<div class="mt-2">
|
||||
<input type="text" name="region" id="region" autocomplete="address-level1" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sm:col-span-2">
|
||||
<label for="postal-code" class="block text-sm font-medium leading-6 text-gray-900">ZIP / Postal code</label>
|
||||
<div class="mt-2">
|
||||
<input type="text" name="postal-code" id="postal-code" autocomplete="postal-code" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-end gap-x-6 border-t border-gray-900/10 px-4 py-4 sm:px-8">
|
||||
<button type="button" class="text-sm font-semibold leading-6 text-gray-900">Cancel</button>
|
||||
<button type="submit" class="rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 gap-x-8 gap-y-8 pt-10 md:grid-cols-3">
|
||||
<div class="px-4 sm:px-0">
|
||||
<h2 class="text-base font-semibold leading-7 text-gray-900">Notifications</h2>
|
||||
<p class="mt-1 text-sm leading-6 text-gray-600">We'll always let you know about important changes, but you pick what else you want to hear about.</p>
|
||||
</div>
|
||||
|
||||
<form class="bg-white shadow-sm ring-1 ring-gray-900/5 sm:rounded-xl md:col-span-2">
|
||||
<div class="px-4 py-6 sm:p-8">
|
||||
<div class="max-w-2xl space-y-10">
|
||||
<fieldset>
|
||||
<legend class="text-sm font-semibold leading-6 text-gray-900">By Email</legend>
|
||||
<div class="mt-6 space-y-6">
|
||||
<div class="relative flex gap-x-3">
|
||||
<div class="flex h-6 items-center">
|
||||
<input id="comments" name="comments" type="checkbox" class="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600">
|
||||
</div>
|
||||
<div class="text-sm leading-6">
|
||||
<label for="comments" class="font-medium text-gray-900">Comments</label>
|
||||
<p class="text-gray-500">Get notified when someones posts a comment on a posting.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex gap-x-3">
|
||||
<div class="flex h-6 items-center">
|
||||
<input id="candidates" name="candidates" type="checkbox" class="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600">
|
||||
</div>
|
||||
<div class="text-sm leading-6">
|
||||
<label for="candidates" class="font-medium text-gray-900">Candidates</label>
|
||||
<p class="text-gray-500">Get notified when a candidate applies for a job.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex gap-x-3">
|
||||
<div class="flex h-6 items-center">
|
||||
<input id="offers" name="offers" type="checkbox" class="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600">
|
||||
</div>
|
||||
<div class="text-sm leading-6">
|
||||
<label for="offers" class="font-medium text-gray-900">Offers</label>
|
||||
<p class="text-gray-500">Get notified when a candidate accepts or rejects an offer.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend class="text-sm font-semibold leading-6 text-gray-900">Push Notifications</legend>
|
||||
<p class="mt-1 text-sm leading-6 text-gray-600">These are delivered via SMS to your mobile phone.</p>
|
||||
<div class="mt-6 space-y-6">
|
||||
<div class="flex items-center gap-x-3">
|
||||
<input id="push-everything" name="push-notifications" type="radio" class="h-4 w-4 border-gray-300 text-indigo-600 focus:ring-indigo-600">
|
||||
<label for="push-everything" class="block text-sm font-medium leading-6 text-gray-900">Everything</label>
|
||||
</div>
|
||||
<div class="flex items-center gap-x-3">
|
||||
<input id="push-email" name="push-notifications" type="radio" class="h-4 w-4 border-gray-300 text-indigo-600 focus:ring-indigo-600">
|
||||
<label for="push-email" class="block text-sm font-medium leading-6 text-gray-900">Same as email</label>
|
||||
</div>
|
||||
<div class="flex items-center gap-x-3">
|
||||
<input id="push-nothing" name="push-notifications" type="radio" class="h-4 w-4 border-gray-300 text-indigo-600 focus:ring-indigo-600">
|
||||
<label for="push-nothing" class="block text-sm font-medium leading-6 text-gray-900">No push notifications</label>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-end gap-x-6 border-t border-gray-900/10 px-4 py-4 sm:px-8">
|
||||
<button type="button" class="text-sm font-semibold leading-6 text-gray-900">Cancel</button>
|
||||
<button type="submit" class="rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
10
apps/front/src/routes/map/+page.svelte
Normal file
10
apps/front/src/routes/map/+page.svelte
Normal file
@ -0,0 +1,10 @@
|
||||
<script lang="ts">
|
||||
import Map from '$lib/client/components/map.svelte';
|
||||
import Table from '$lib/client/components/table.svelte';
|
||||
</script>
|
||||
|
||||
<Map />
|
||||
|
||||
<div class="mt-10">
|
||||
<Table />
|
||||
</div>
|
BIN
apps/front/static/favicon.png
Normal file
BIN
apps/front/static/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
18
apps/front/svelte.config.js
Normal file
18
apps/front/svelte.config.js
Normal file
@ -0,0 +1,18 @@
|
||||
import adapter from '@sveltejs/adapter-auto';
|
||||
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
||||
// for more information about preprocessors
|
||||
preprocess: vitePreprocess(),
|
||||
|
||||
kit: {
|
||||
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
|
||||
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
|
||||
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
|
||||
adapter: adapter()
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
9
apps/front/tailwind.config.js
Normal file
9
apps/front/tailwind.config.js
Normal file
@ -0,0 +1,9 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: ['./src/**/*.{html,js,svelte,ts}'],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [require('@tailwindcss/forms'),],
|
||||
}
|
||||
|
18
apps/front/tsconfig.json
Normal file
18
apps/front/tsconfig.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"extends": "./.svelte-kit/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"moduleResolution": "bundler"
|
||||
}
|
||||
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
|
||||
//
|
||||
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
||||
// from the referenced tsconfig.json - TypeScript does not merge them in
|
||||
}
|
9
apps/front/vite.config.ts
Normal file
9
apps/front/vite.config.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
import { defineConfig } from 'vitest/config';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [sveltekit()],
|
||||
test: {
|
||||
include: ['src/**/*.{test,spec}.{js,ts}']
|
||||
}
|
||||
});
|
@ -90,16 +90,17 @@ CREATE TABLE devices
|
||||
device_group_id INT4 NOT NULL,
|
||||
name VARCHAR(50) NOT NULL,
|
||||
lamppost_number VARCHAR(50), -- QUESTION: What type is lamppost_number? Is it a string or an integer?
|
||||
index INT2 NOT NULL DEFAULT 0, -- The index of the device in the sequence of devices in the device group / lampposts in the street. Used for ordering & switching on/off alternatively.
|
||||
started_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, -- for calculating the uptime/running hours
|
||||
lux_level INT2,
|
||||
role INT2 NOT NULL DEFAULT 0, -- 0 - light, 1 - motion sensor, 2 - gateway, maybe more roles in the future
|
||||
role INT2 NOT NULL DEFAULT 0, -- 0 - lamppost light, 1 - spike light, 2 - motion sensor, 3 - gateway, maybe more roles in the future
|
||||
|
||||
-- geolocation. We can use Postgres plugin "PostGIS" for this, but it's not necessary for now
|
||||
latitude FLOAT4,
|
||||
longitude FLOAT4,
|
||||
altitude FLOAT4,
|
||||
|
||||
status INT2 NOT NULL DEFAULT 0, -- 0 - off, 1 - on, maybe more statuses in the future
|
||||
status INT2 NOT NULL DEFAULT 0, -- 0 - off, 1 - on, 2 - fault, maybe more statuses in the future
|
||||
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (device_group_id) REFERENCES device_groups (id) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
|
Loading…
x
Reference in New Issue
Block a user