Prima release
This commit is contained in:
@@ -3,3 +3,6 @@ dist/
|
||||
node_modules/
|
||||
|
||||
*.local*
|
||||
|
||||
.env
|
||||
.env.production
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"dependencies": {
|
||||
"date-fns": "^2.29.2",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash-es": "^4.17.21",
|
||||
"preact": "^10.10.6",
|
||||
"sass": "^1.54.8",
|
||||
"vite": "^3.0.9"
|
||||
|
||||
Generated
+6
@@ -5,6 +5,7 @@ specifiers:
|
||||
'@preact/preset-vite': ^2.3.0
|
||||
date-fns: ^2.29.2
|
||||
lodash: ^4.17.21
|
||||
lodash-es: ^4.17.21
|
||||
preact: ^10.10.6
|
||||
sass: ^1.54.8
|
||||
vite: ^3.0.9
|
||||
@@ -12,6 +13,7 @@ specifiers:
|
||||
dependencies:
|
||||
date-fns: 2.29.2
|
||||
lodash: 4.17.21
|
||||
lodash-es: 4.17.21
|
||||
preact: 10.10.6
|
||||
sass: 1.54.8
|
||||
vite: 3.0.9_sass@1.54.8
|
||||
@@ -777,6 +779,10 @@ packages:
|
||||
resolution: {integrity: sha512-lxpCM3HTvquGxKGzHeknB/sUjuVoUElLlfYnXZT73K8geR9jQbroGlSCFBax9/0mpGoD3kzcMLnOlGQPJJNyqQ==}
|
||||
dev: true
|
||||
|
||||
/lodash-es/4.17.21:
|
||||
resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
|
||||
dev: false
|
||||
|
||||
/lodash/4.17.21:
|
||||
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
|
||||
dev: false
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
<svg width="1000" height="500" viewBox="0 0 1000 500" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="80" y="190" width="60" height="120" fill="#1E6733"/>
|
||||
<rect x="160" y="50" width="150" height="60" fill="#1E6733"/>
|
||||
<rect x="140" y="90" width="10" height="50" fill="#ECC333"/>
|
||||
<rect x="140" y="200" width="10" height="50" fill="#ECC333"/>
|
||||
<rect x="140" y="410" width="10" height="20" fill="#ECC333"/>
|
||||
<rect x="140" y="350" width="10" height="50" fill="#ECC333"/>
|
||||
<rect x="240" y="110" width="70" height="10" fill="#ECC333"/>
|
||||
<rect x="250" y="130" width="60" height="130" fill="#1E6733"/>
|
||||
<rect x="340" y="50" width="60" height="120" fill="#1E6733"/>
|
||||
<rect x="340" y="190" width="60" height="120" fill="#1E6733"/>
|
||||
<rect x="590" y="190" width="60" height="120" fill="#1E6733"/>
|
||||
<rect x="690" y="180" width="60" height="120" fill="#1E6733"/>
|
||||
<rect x="690" y="310" width="60" height="140" fill="#1E6733"/>
|
||||
<rect x="690" y="50" width="60" height="120" fill="#1E6733"/>
|
||||
<rect x="590" y="320" width="60" height="130" fill="#1E6733"/>
|
||||
<rect x="590" y="50" width="60" height="130" fill="#1E6733"/>
|
||||
<rect x="420" y="240" width="150" height="60" fill="#1E6733"/>
|
||||
<rect x="340" y="320" width="60" height="130" fill="#1E6733"/>
|
||||
<rect x="240" y="140" width="10" height="50" fill="#ECC333"/>
|
||||
<rect x="350" y="170" width="40" height="10" fill="#ECC333"/>
|
||||
<rect x="330" y="330" width="10" height="50" fill="#ECC333"/>
|
||||
<rect x="160" y="200" width="80" height="60" fill="#1E6733"/>
|
||||
<rect x="650" y="200" width="10" height="50" fill="#ECC333"/>
|
||||
<rect x="750" y="330" width="10" height="60" fill="#ECC333"/>
|
||||
<rect x="800" y="450" width="40" height="10" fill="#ECC333"/>
|
||||
<rect x="850" y="450" width="30" height="10" fill="#ECC333"/>
|
||||
<rect x="750" y="90" width="10" height="50" fill="#ECC333"/>
|
||||
<rect x="810" y="110" width="60" height="10" fill="#ECC333"/>
|
||||
<rect x="580" y="330" width="10" height="50" fill="#ECC333"/>
|
||||
<rect x="580" y="60" width="10" height="50" fill="#ECC333"/>
|
||||
<rect x="710" y="420" width="20" height="20" fill="#C4C4C4"/>
|
||||
<rect x="710" y="390" width="20" height="20" fill="#C4C4C4"/>
|
||||
<rect x="100" y="280" width="20" height="10" fill="#C4C4C4"/>
|
||||
<rect x="100" y="260" width="20" height="10" fill="#C4C4C4"/>
|
||||
<rect x="110" y="210" width="20" height="20" fill="#C4C4C4"/>
|
||||
<rect x="350" y="430" width="40" height="10" fill="#303030"/>
|
||||
<rect x="350" y="410" width="40" height="10" fill="#303030"/>
|
||||
<rect x="350" y="390" width="40" height="10" fill="#303030"/>
|
||||
<rect x="700" y="70" width="20" height="40" fill="#303030"/>
|
||||
<rect x="700" y="120" width="20" height="40" fill="#303030"/>
|
||||
<rect x="610" y="280" width="20" height="20" fill="#C4C4C4"/>
|
||||
<rect x="600" y="240" width="20" height="20" fill="#C4C4C4"/>
|
||||
<rect x="430" y="250" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="430" y="265" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="430" y="280" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="445" y="250" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="445" y="265" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="460" y="280" width="40" height="10" fill="#C4C4C4"/>
|
||||
<rect x="475" y="250" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="475" y="265" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="505" y="250" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="505" y="265" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="520" y="265" width="10" height="15" fill="#C4C4C4"/>
|
||||
<rect x="505" y="280" width="25" height="10" fill="#C4C4C4"/>
|
||||
<rect x="535" y="250" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="535" y="265" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="535" y="280" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="445" y="280" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="460" y="250" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="460" y="265" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="490" y="250" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="490" y="265" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="520" y="250" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="550" y="250" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="550" y="265" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="550" y="280" width="10" height="10" fill="#C4C4C4"/>
|
||||
<rect x="620" y="210" width="20" height="20" fill="#C4C4C4"/>
|
||||
<rect x="370" y="70" width="20" height="30" fill="#303030"/>
|
||||
<rect x="370" y="110" width="20" height="30" fill="#303030"/>
|
||||
<rect x="870" y="440" width="40" height="10" transform="rotate(-90 870 440)" fill="#303030"/>
|
||||
<rect x="890" y="440" width="40" height="10" transform="rotate(-90 890 440)" fill="#303030"/>
|
||||
<rect x="810" y="440" width="40" height="10" transform="rotate(-90 810 440)" fill="#303030"/>
|
||||
<rect x="790" y="440" width="40" height="10" transform="rotate(-90 790 440)" fill="#303030"/>
|
||||
<rect x="270" y="100" width="40" height="10" transform="rotate(-90 270 100)" fill="#303030"/>
|
||||
<rect x="290" y="100" width="40" height="10" transform="rotate(-90 290 100)" fill="#303030"/>
|
||||
<rect x="190" y="100" width="40" height="10" transform="rotate(-90 190 100)" fill="#303030"/>
|
||||
<rect x="170" y="100" width="40" height="10" transform="rotate(-90 170 100)" fill="#303030"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M140 60V170C134.477 170 130 174.477 130 180H90C90 174.477 85.5228 170 80 170V60C85.5228 60 90 55.5228 90 50H130C130 55.5228 134.477 60 140 60Z" fill="#1E6733"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M130 320H90C90 325.523 85.5229 330 80 330V440C85.5229 440 90 444.477 90 450H130C130 444.477 134.477 440 140 440V330C134.477 330 130 325.523 130 320Z" fill="#1E6733"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M770 60C775.523 60 780 55.5228 780 50H910C910 55.5228 914.477 60 920 60V100C914.477 100 910 104.477 910 110H780C780 104.477 775.523 100 770 100V60Z" fill="#1E6733"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M770 400C775.523 400 780 395.523 780 390H910C910 395.523 914.477 400 920 400V440C914.477 440 910 444.477 910 450H780C780 444.477 775.523 440 770 440V400Z" fill="#1E6733"/>
|
||||
<rect x="750" y="190" width="10" height="40" fill="#ECC333"/>
|
||||
<rect x="750" y="240" width="10" height="20" fill="#ECC333"/>
|
||||
<rect x="400" y="200" width="10" height="40" fill="#ECC333"/>
|
||||
<rect x="400" y="250" width="10" height="20" fill="#ECC333"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.1 KiB |
@@ -1,19 +1,28 @@
|
||||
import { useRef } from 'preact/hooks'
|
||||
import { useRef, useState } from 'preact/hooks'
|
||||
import { Icon } from './Icon.jsx'
|
||||
|
||||
export const ComboBox = ({ selected, options }) => {
|
||||
let ids = 0
|
||||
|
||||
function generateId() {
|
||||
return 'combo-id-' + ids++
|
||||
}
|
||||
|
||||
export const ComboBox = ({ options, value, setValue }) => {
|
||||
const [uid] = useState(() => generateId())
|
||||
const selectRef = useRef()
|
||||
|
||||
return (
|
||||
<div class="input-combo" onClick={() => selectRef.current?.click()}>
|
||||
<select ref={selectRef}>
|
||||
{options.map(({ label, value }) => (
|
||||
<option value={value} selected={value === selected}>
|
||||
{label}
|
||||
<div class="input-combo">
|
||||
<select ref={selectRef} id={uid} onInput={e => setValue(e.target.value)}>
|
||||
{options.map(option => (
|
||||
<option value={option.value} selected={option.value === value}>
|
||||
{option.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<Icon name="expand_more" />
|
||||
<label class="icon" for={uid}>
|
||||
<Icon name="expand_more" />
|
||||
</label>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { withClasses } from '../utils.jsx'
|
||||
|
||||
export const CompoundButton = ({ options, value, setValue }) => {
|
||||
return (
|
||||
<div class="compound">
|
||||
{options.map(option => (
|
||||
<button
|
||||
class={withClasses(['radio', option.value === value && 'selected'])}
|
||||
onClick={() => setValue(option.value)}
|
||||
>
|
||||
{option.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ComboBox } from './ComboBox.jsx'
|
||||
import { Icon } from './Icon.jsx'
|
||||
|
||||
export const HamburgerMenu = ({ onClose }) => {
|
||||
export const HamburgerMenu = ({ onClose, mode, setMode, source, setSource }) => {
|
||||
return (
|
||||
<div class="menu">
|
||||
<div class="header">
|
||||
@@ -11,12 +11,29 @@ export const HamburgerMenu = ({ onClose }) => {
|
||||
<div class="item logo">PHC / Orari</div>
|
||||
</div>
|
||||
<div class="options">
|
||||
<div class="label">Gruppo Corsi</div>
|
||||
<ComboBox
|
||||
selected={1}
|
||||
value={source}
|
||||
setValue={setSource}
|
||||
options={[
|
||||
{ label: 'Prova 1', value: 1 },
|
||||
{ label: 'Prova 2', value: 2 },
|
||||
{ label: 'Prova 3', value: 3 },
|
||||
{ value: 'anno-1', label: 'I' },
|
||||
{ value: 'anno-2', label: 'II' },
|
||||
{ value: 'anno-3', label: 'III' },
|
||||
{ value: 'magistrale', label: 'Magistrale' },
|
||||
{ value: 'tutti', label: 'Tutti' },
|
||||
]}
|
||||
/>
|
||||
<div class="label">Visualizzazione</div>
|
||||
<ComboBox
|
||||
value={mode}
|
||||
setValue={setMode}
|
||||
options={[
|
||||
{ value: 'course', label: 'Corsi' },
|
||||
{ value: 'work-week-v', label: 'Settimana' },
|
||||
{
|
||||
value: 'work-week-h',
|
||||
label: 'Settimana (Trasposto)',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
export const Icon = ({ name }) => <span class="material-symbols-outlined">{name}</span>
|
||||
export const Icon = ({ name, ...rest }) => (
|
||||
<span class="material-symbols-outlined" {...rest}>
|
||||
{name}
|
||||
</span>
|
||||
)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Icon } from './Icon.jsx'
|
||||
|
||||
export const Popup = ({ title, children, onClose }) => {
|
||||
return (
|
||||
<div class="popup-container">
|
||||
<div class="popup">
|
||||
<div class="header">
|
||||
<div class="title">{title}</div>
|
||||
<button class="flat icon" onClick={onClose}>
|
||||
<Icon name="close" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="content">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
+41
-58
@@ -1,6 +1,7 @@
|
||||
import { CompoundButton } from './CompoundButton.jsx'
|
||||
import { Icon } from './Icon.jsx'
|
||||
|
||||
export const Toolbar = ({ mode, setMode, source, setSource, onShowMenu }) => {
|
||||
export const Toolbar = ({ mode, setMode, source, setSource, onShowMenu, onHelp }) => {
|
||||
return (
|
||||
<div class="toolbar">
|
||||
<div class="mobile">
|
||||
@@ -8,72 +9,54 @@ export const Toolbar = ({ mode, setMode, source, setSource, onShowMenu }) => {
|
||||
<Icon name="menu" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="item logo">PHC / Orari</div>
|
||||
<div class="item logo">
|
||||
<img src="logo-circuit-board.svg" alt="logo" /> / <span>Orari</span>
|
||||
</div>
|
||||
<div class="option-group">
|
||||
<div class="item option">
|
||||
<div class="compound">
|
||||
<button
|
||||
class={'radio' + (source === 'anno-1' ? ' selected' : '')}
|
||||
onClick={() => setSource('anno-1')}
|
||||
>
|
||||
I
|
||||
</button>
|
||||
<button
|
||||
class={'radio' + (source === 'anno-2' ? ' selected' : '')}
|
||||
onClick={() => setSource('anno-2')}
|
||||
>
|
||||
II
|
||||
</button>
|
||||
<button
|
||||
class={'radio' + (source === 'anno-3' ? ' selected' : '')}
|
||||
onClick={() => setSource('anno-3')}
|
||||
>
|
||||
III
|
||||
</button>
|
||||
<button
|
||||
class={'radio' + (source === 'magistrale' ? ' selected' : '')}
|
||||
onClick={() => setSource('magistrale')}
|
||||
>
|
||||
Magistrale
|
||||
</button>
|
||||
{/* TODO: Aggiungere il pulsante per "tutti" */}
|
||||
{/* <button
|
||||
class={'radio' + (source === 'tutti' ? ' selected' : '')}
|
||||
onClick={() => setSource('tutti')}
|
||||
>
|
||||
Tutti
|
||||
</button> */}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item option">
|
||||
<div class="compound">
|
||||
<button
|
||||
class={'radio' + (mode === 'course' ? ' selected' : '')}
|
||||
onClick={() => setMode('course')}
|
||||
>
|
||||
Corso
|
||||
</button>
|
||||
<button
|
||||
class={'radio' + (mode === 'work-week-v' ? ' selected' : '')}
|
||||
onClick={() => setMode('work-week-v')}
|
||||
>
|
||||
Settimana
|
||||
</button>
|
||||
<button
|
||||
class={'radio' + (mode === 'work-week-h' ? ' selected' : '')}
|
||||
onClick={() => setMode('work-week-h')}
|
||||
>
|
||||
Settimana<sup>T</sup>
|
||||
</button>
|
||||
</div>
|
||||
<CompoundButton
|
||||
options={[
|
||||
{ value: 'anno-1', label: 'I' },
|
||||
{ value: 'anno-2', label: 'II' },
|
||||
{ value: 'anno-3', label: 'III' },
|
||||
{ value: 'magistrale', label: 'Magistrale' },
|
||||
{ value: 'tutti', label: 'Tutti' },
|
||||
]}
|
||||
value={source}
|
||||
setValue={setSource}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="option-group">
|
||||
<div class="item option">
|
||||
<button class="icon">
|
||||
<CompoundButton
|
||||
options={[
|
||||
{ value: 'course', label: 'Corsi' },
|
||||
{ value: 'work-week-v', label: 'Settimana' },
|
||||
{
|
||||
value: 'work-week-h',
|
||||
label: (
|
||||
<>
|
||||
<Icon name="warning" />
|
||||
Settimana<sup>T</sup>
|
||||
</>
|
||||
),
|
||||
},
|
||||
]}
|
||||
value={mode}
|
||||
setValue={setMode}
|
||||
/>
|
||||
</div>
|
||||
<div class="item option">
|
||||
<button class="icon" onClick={() => window.print()}>
|
||||
<Icon name="print" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="item option">
|
||||
<button class="icon" onClick={onHelp}>
|
||||
<Icon name="question_mark" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
+147
-48
@@ -5,68 +5,84 @@ import { ToolOverlay } from './components/CourseVisibility.jsx'
|
||||
|
||||
import { EventsView } from './components/EventsView.jsx'
|
||||
import { HamburgerMenu } from './components/HamburgerMenu.jsx'
|
||||
import { Icon } from './components/Icon.jsx'
|
||||
import { Popup } from './components/Popup.jsx'
|
||||
import { Toolbar } from './components/Toolbar.jsx'
|
||||
|
||||
window._ = _
|
||||
window.dataBuffer = {}
|
||||
// window._ = _
|
||||
// window.dataBuffer = {}
|
||||
|
||||
const CALENDAR_IDS = {
|
||||
'anno-1': '6308cfcb1df5cb026699ce32',
|
||||
'anno-2': '6308e2dc09352a0208fefdd9',
|
||||
'anno-3': '6308e42a1df5cb026699ced4',
|
||||
'magistrale': '6308e8ea0c34e703bb1f7e85',
|
||||
'anno-1': ['6308cfcb1df5cb026699ce32'],
|
||||
'anno-2': ['6308e2dc09352a0208fefdd9'],
|
||||
'anno-3': ['6308e42a1df5cb026699ced4'],
|
||||
'magistrale': ['6308e8ea0c34e703bb1f7e85'],
|
||||
'tutti': [
|
||||
'6308cfcb1df5cb026699ce32',
|
||||
'6308e2dc09352a0208fefdd9',
|
||||
'6308e42a1df5cb026699ced4',
|
||||
'6308e8ea0c34e703bb1f7e85',
|
||||
],
|
||||
}
|
||||
|
||||
async function loadEventi(ids) {
|
||||
const calendari = await Promise.all(
|
||||
ids.map(async id => {
|
||||
// Almost directly copy-pasted from Chrome Dev Tools
|
||||
const req = await fetch(
|
||||
'https://apache.prod.up.cineca.it/api/Impegni/getImpegniCalendarioPubblico',
|
||||
{
|
||||
headers: {
|
||||
'content-type': 'application/json;charset=UTF-8',
|
||||
'sec-fetch-dest': 'empty',
|
||||
'sec-fetch-mode': 'cors',
|
||||
'sec-fetch-site': 'same-site',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
mostraImpegniAnnullati: true,
|
||||
mostraIndisponibilitaTotali: false,
|
||||
linkCalendarioId: id,
|
||||
clienteId: '628de8b9b63679f193b87046',
|
||||
pianificazioneTemplate: false,
|
||||
dataInizio: '2022-10-02T22:00:00.000Z',
|
||||
dataFine: '2022-10-07T22:00:00.000Z',
|
||||
}),
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
credentials: 'omit',
|
||||
}
|
||||
)
|
||||
|
||||
return await req.json()
|
||||
})
|
||||
)
|
||||
|
||||
console.log(calendari)
|
||||
|
||||
if (ids.length === 1) {
|
||||
return calendari[0]
|
||||
}
|
||||
|
||||
return _.uniqBy(_.concat(...calendari), 'id')
|
||||
}
|
||||
|
||||
const App = ({}) => {
|
||||
const [source, setSource] = useState('magistrale')
|
||||
|
||||
const [eventi, setEventi] = useState([])
|
||||
|
||||
const [selectedCourses, setSelectedCourses] = useState([])
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedCourses([])
|
||||
}, [source])
|
||||
|
||||
useEffect(() => {
|
||||
// Directly copy-pasted from chrome Dev Tools
|
||||
const request = fetch(
|
||||
'https://apache.prod.up.cineca.it/api/Impegni/getImpegniCalendarioPubblico',
|
||||
{
|
||||
headers: {
|
||||
'content-type': 'application/json;charset=UTF-8',
|
||||
'sec-fetch-dest': 'empty',
|
||||
'sec-fetch-mode': 'cors',
|
||||
'sec-fetch-site': 'same-site',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
mostraImpegniAnnullati: true,
|
||||
mostraIndisponibilitaTotali: false,
|
||||
linkCalendarioId: CALENDAR_IDS[source],
|
||||
clienteId: '628de8b9b63679f193b87046',
|
||||
pianificazioneTemplate: false,
|
||||
dataInizio: '2022-10-02T22:00:00.000Z',
|
||||
dataFine: '2022-10-07T22:00:00.000Z',
|
||||
}),
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
credentials: 'omit',
|
||||
}
|
||||
)
|
||||
|
||||
// const request = fetch('/data.json')
|
||||
|
||||
console.time('loading eventi')
|
||||
|
||||
request
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
console.timeEnd('loading eventi')
|
||||
window.dataBuffer[source] = data
|
||||
setEventi(data)
|
||||
})
|
||||
useEffect(async () => {
|
||||
const eventi = await loadEventi(CALENDAR_IDS[source])
|
||||
// window.dataBuffer[source] = eventi
|
||||
setEventi(eventi)
|
||||
}, [source])
|
||||
|
||||
const [helpVisible, setHelpVisible] = useState(false)
|
||||
|
||||
const [mode, setMode] = useState('course')
|
||||
|
||||
const [hideOtherCourses, setHideOtherCourses] = useState(false)
|
||||
@@ -76,7 +92,7 @@ const App = ({}) => {
|
||||
setHideOtherCourses(false)
|
||||
}
|
||||
|
||||
const [showMobileMenu, setShowMobileMenu] = useState(true)
|
||||
const [showMobileMenu, setShowMobileMenu] = useState(false)
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -87,6 +103,7 @@ const App = ({}) => {
|
||||
source,
|
||||
setSource,
|
||||
onShowMenu: () => setShowMobileMenu(true),
|
||||
onHelp: () => setHelpVisible(true),
|
||||
}}
|
||||
/>
|
||||
<EventsView
|
||||
@@ -120,11 +137,93 @@ const App = ({}) => {
|
||||
)}
|
||||
{showMobileMenu && (
|
||||
<HamburgerMenu
|
||||
onClose={() => {
|
||||
setShowMobileMenu(false)
|
||||
{...{
|
||||
mode,
|
||||
setMode,
|
||||
source,
|
||||
setSource,
|
||||
onClose: () => {
|
||||
setShowMobileMenu(false)
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{helpVisible && (
|
||||
<Popup
|
||||
title={
|
||||
<>
|
||||
<Icon name="info" /> Aiuto
|
||||
</>
|
||||
}
|
||||
onClose={() => setHelpVisible(false)}
|
||||
>
|
||||
<h1>Titolo</h1>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Similique eum
|
||||
pariatur amet. Laborum quos repudiandae corrupti, exercitationem cum labore
|
||||
doloribus.
|
||||
</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Similique eum
|
||||
pariatur amet. Laborum quos repudiandae corrupti, exercitationem cum labore
|
||||
doloribus.
|
||||
</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Similique eum
|
||||
pariatur amet. Laborum quos repudiandae corrupti, exercitationem cum labore
|
||||
doloribus.
|
||||
</p>
|
||||
<h2>Sottotitolo</h2>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Similique eum
|
||||
pariatur amet. Laborum quos repudiandae corrupti, exercitationem cum labore
|
||||
doloribus.
|
||||
</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Similique eum
|
||||
pariatur amet. Laborum quos repudiandae corrupti, exercitationem cum labore
|
||||
doloribus.
|
||||
</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Similique eum
|
||||
pariatur amet. Laborum quos repudiandae corrupti, exercitationem cum labore
|
||||
doloribus.
|
||||
</p>
|
||||
<h2>Sottotitolo</h2>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Similique eum
|
||||
pariatur amet. Laborum quos repudiandae corrupti, exercitationem cum labore
|
||||
doloribus.
|
||||
</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Similique eum
|
||||
pariatur amet. Laborum quos repudiandae corrupti, exercitationem cum labore
|
||||
doloribus.
|
||||
</p>
|
||||
<h3>Sottosottotitolo</h3>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Similique eum
|
||||
pariatur amet. Laborum quos repudiandae corrupti, exercitationem cum labore
|
||||
doloribus.
|
||||
</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Similique eum
|
||||
pariatur amet. Laborum quos repudiandae corrupti, exercitationem cum labore
|
||||
doloribus.
|
||||
</p>
|
||||
<h3>Sottosottotitolo</h3>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Similique eum
|
||||
pariatur amet. Laborum quos repudiandae corrupti, exercitationem cum labore
|
||||
doloribus.
|
||||
</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Similique eum
|
||||
pariatur amet. Laborum quos repudiandae corrupti, exercitationem cum labore
|
||||
doloribus.
|
||||
</p>
|
||||
</Popup>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
+183
-19
@@ -38,7 +38,7 @@ html {
|
||||
--accent-900: #244624;
|
||||
}
|
||||
|
||||
$device-s-width: 480px;
|
||||
$device-s-width: 420px;
|
||||
|
||||
// Elements
|
||||
|
||||
@@ -51,12 +51,43 @@ sup {
|
||||
transform: translate(0, -0.25rem);
|
||||
}
|
||||
|
||||
// Headings
|
||||
|
||||
$base-font-size: 18px;
|
||||
$heading-scale: 1.25;
|
||||
|
||||
@function pow($number, $exponent) {
|
||||
$value: 1;
|
||||
|
||||
@if $exponent > 0 {
|
||||
@for $i from 1 through $exponent {
|
||||
$value: $value * $number;
|
||||
}
|
||||
}
|
||||
|
||||
@return $value;
|
||||
}
|
||||
|
||||
@for $i from 1 through 4 {
|
||||
h#{$i} {
|
||||
margin: 0;
|
||||
|
||||
$factor: pow($heading-scale, 4 - $i);
|
||||
font-size: $base-font-size * $factor;
|
||||
font-weight: 500;
|
||||
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
button,
|
||||
.button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
gap: 0.25rem;
|
||||
|
||||
background: var(--gray-000);
|
||||
border: 2px solid var(--gray-350);
|
||||
border-radius: 0.5rem;
|
||||
@@ -94,11 +125,15 @@ button,
|
||||
&.icon {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
&.flat {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.input-combo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
// align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
height: 3rem;
|
||||
@@ -109,15 +144,13 @@ button,
|
||||
|
||||
font-weight: 400;
|
||||
|
||||
padding: 0.5rem 0.5rem 0.5rem 1rem;
|
||||
// padding: 0.5rem 0.5rem 0.5rem 1rem;
|
||||
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
|
||||
position: relative;
|
||||
|
||||
gap: 0.5rem;
|
||||
|
||||
select {
|
||||
border: none;
|
||||
background: none;
|
||||
@@ -125,14 +158,92 @@ button,
|
||||
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
font-weight: 300;
|
||||
|
||||
height: 100%;
|
||||
padding-left: 1rem;
|
||||
padding-right: 3rem;
|
||||
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.icon {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
|
||||
height: 100%;
|
||||
width: calc(3rem - 4px);
|
||||
|
||||
display: grid;
|
||||
place-content: center;
|
||||
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Components
|
||||
|
||||
.popup-container {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
|
||||
z-index: 10;
|
||||
|
||||
background: #00000099;
|
||||
|
||||
max-width: 100%;
|
||||
|
||||
.popup {
|
||||
@extend .panel;
|
||||
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
|
||||
box-shadow: 0 0 1.5rem #00000033;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
user-select: none;
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
@extend .text-block;
|
||||
|
||||
width: 60ch;
|
||||
max-width: 100%;
|
||||
max-height: 60vh;
|
||||
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.compound {
|
||||
display: flex;
|
||||
|
||||
.material-symbols-outlined {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
button,
|
||||
.button {
|
||||
border-radius: 0;
|
||||
@@ -175,6 +286,8 @@ button,
|
||||
}
|
||||
}
|
||||
|
||||
// Extension Classes
|
||||
|
||||
.panel {
|
||||
background: var(--gray-000);
|
||||
border: 1px solid var(--gray-500);
|
||||
@@ -182,6 +295,12 @@ button,
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.text-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
// Structure
|
||||
|
||||
body {
|
||||
@@ -190,6 +309,8 @@ body {
|
||||
|
||||
font-weight: 300;
|
||||
font-family: 'Inter', sans-serif;
|
||||
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
@@ -213,10 +334,22 @@ body {
|
||||
|
||||
gap: 1rem;
|
||||
|
||||
@media screen and (max-width: $device-s-width) {
|
||||
@media screen and (max-width: $device-s-width) and (orientation: portrait),
|
||||
screen and (max-height: $device-s-width) and (orientation: landscape) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
max-height: 2.5rem;
|
||||
}
|
||||
|
||||
gap: 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
.events-view {
|
||||
@@ -254,6 +387,8 @@ body {
|
||||
|
||||
position: relative;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
&.selected {
|
||||
background: var(--gray-100);
|
||||
|
||||
@@ -308,6 +443,10 @@ body {
|
||||
.day {
|
||||
box-sizing: content-box;
|
||||
|
||||
// @media screen and (max-width: $device-s-width) {
|
||||
// writing-mode: vertical-lr;
|
||||
// }
|
||||
|
||||
height: calc(var(--size) * var(--event-height) + (var(--size) - 1) * 0.25rem);
|
||||
|
||||
border-top: 1px solid var(--gray-500);
|
||||
@@ -452,7 +591,7 @@ body {
|
||||
|
||||
overflow: scroll;
|
||||
|
||||
--event-height: 4.25rem;
|
||||
--event-height: 4.75rem;
|
||||
|
||||
.pivot {
|
||||
height: 3rem;
|
||||
@@ -507,7 +646,8 @@ body {
|
||||
|
||||
border-top: 1px solid var(--gray-500);
|
||||
|
||||
@media screen and (max-width: $device-s-width) {
|
||||
@media screen and (max-width: $device-s-width) and (orientation: portrait),
|
||||
screen and (max-height: $device-s-width) and (orientation: landscape) {
|
||||
writing-mode: vertical-lr;
|
||||
}
|
||||
|
||||
@@ -658,7 +798,9 @@ body {
|
||||
}
|
||||
|
||||
// not on mobile
|
||||
@media screen and (min-width: $device-s-width) {
|
||||
|
||||
@media screen and (min-width: $device-s-width) and (orientation: portrait),
|
||||
screen and (min-height: $device-s-width) and (orientation: landscape) {
|
||||
.mobile {
|
||||
display: none;
|
||||
}
|
||||
@@ -669,20 +811,19 @@ body {
|
||||
}
|
||||
|
||||
// on mobile
|
||||
@media screen and (max-width: $device-s-width) {
|
||||
|
||||
@media screen and (max-width: $device-s-width) and (orientation: portrait),
|
||||
screen and (max-height: $device-s-width) and (orientation: landscape) {
|
||||
.toolbar {
|
||||
padding: 0.75rem 1rem 0.75rem 0.75rem;
|
||||
}
|
||||
|
||||
button {
|
||||
&.flat {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.menu {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
|
||||
background: var(--gray-000);
|
||||
|
||||
@@ -703,13 +844,36 @@ body {
|
||||
.options {
|
||||
padding: 1rem;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
|
||||
gap: 1rem;
|
||||
|
||||
align-items: center;
|
||||
|
||||
.label {
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media print {
|
||||
// @page {
|
||||
// size: A4 landscape;
|
||||
// }
|
||||
|
||||
.toolbar,
|
||||
.menu,
|
||||
.overlay {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.work-week-v-view {
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fade-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
export const withClasses = classes =>
|
||||
Array.isArray(classes)
|
||||
? classes.filter(e => !!e).join(' ')
|
||||
: Object.entries(classes)
|
||||
.filter(([, value]) => value)
|
||||
.map(([key]) => key)
|
||||
.join(' ')
|
||||
+16
-5
@@ -1,10 +1,21 @@
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
import preact from '@preact/preset-vite'
|
||||
import { loadEnv } from 'vite'
|
||||
|
||||
export default defineConfig({
|
||||
server: {
|
||||
port: 3000,
|
||||
},
|
||||
plugins: [preact()],
|
||||
export default defineConfig(({ mode }) => {
|
||||
console.log(`Build Mode: "${mode}"`)
|
||||
|
||||
const env = loadEnv(mode, process.cwd(), '')
|
||||
|
||||
return {
|
||||
base: mode === 'development' ? '/' : env.BASE_URL,
|
||||
server: {
|
||||
port: 3000,
|
||||
},
|
||||
plugins: [preact()],
|
||||
esbuild: {
|
||||
logOverride: { 'this-is-undefined-in-esm': 'silent' },
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user