From 7e7e3ef50030b73d7c5a6171cf17e2e14c91ea7e Mon Sep 17 00:00:00 2001 From: "Gleb O. Ivaniczkij" Date: Sat, 17 Aug 2024 00:52:52 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B0=D0=B7=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=B0=D0=BD=D0=BE=20=D0=BD=D0=B5=D1=81=D0=BA=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=BA=D0=BE=20=D0=BA=D0=BE=D0=BC=D0=BF=D0=BE=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D1=82=D0=BE=D0=B2=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84?= =?UTF-8?q?=D0=B5=D0=B9=D1=81=D0=B0=20=D0=B2=D0=B5=D0=B1-=D0=BF=D1=80?= =?UTF-8?q?=D0=B8=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/public/index.html | 1 + frontend/src/App.css | 4 --- frontend/src/App.js | 9 +++--- frontend/src/FullScreenDialog.css | 45 ++++++++++++++++++++++++++ frontend/src/FullScreenDialog.js | 28 +++++++++++++++++ frontend/src/PollList.css | 4 +++ frontend/src/PollList.js | 37 ++++++++++++++++++++++ frontend/src/PollListItem.css | 20 ++++++++++++ frontend/src/PollListItem.js | 22 +++++++++++++ frontend/src/index.css | 4 +++ frontend/src/index.js | 14 ++++----- web/main.py | 52 +++++++++++++++++++++++++------ 12 files changed, 216 insertions(+), 24 deletions(-) create mode 100644 frontend/src/FullScreenDialog.css create mode 100644 frontend/src/FullScreenDialog.js create mode 100644 frontend/src/PollList.css create mode 100644 frontend/src/PollList.js create mode 100644 frontend/src/PollListItem.css create mode 100644 frontend/src/PollListItem.js diff --git a/frontend/public/index.html b/frontend/public/index.html index ac44052..cda3c3e 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -19,6 +19,7 @@ link.type = 'text/css' document.head.append(link) + window.Telegram.WebApp.expand() window.Telegram.WebApp.ready() }) diff --git a/frontend/src/App.css b/frontend/src/App.css index 386bf61..0320773 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -12,10 +12,6 @@ scroll-behavior: smooth; } -main { - padding: 1rem; -} - main > * { width: 100%; } diff --git a/frontend/src/App.js b/frontend/src/App.js index f69e5a7..5ecd634 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -1,7 +1,7 @@ -import React, { useEffect } from 'react'; +import React, { useEffect } from 'react' +import { styles as typescaleStyles } from '@material/web/typography/md-typescale-styles.js' -import { styles as typescaleStyles } from '@material/web/typography/md-typescale-styles.js'; -import '@material/web/switch/switch.js'; +import PollList from "./PollList"; import './App.css' @@ -9,10 +9,11 @@ function App() { useEffect(() => { document.adoptedStyleSheets = [typescaleStyles.styleSheet] }, []) + return (
- +
//
//
diff --git a/frontend/src/FullScreenDialog.css b/frontend/src/FullScreenDialog.css new file mode 100644 index 0000000..fcfbd20 --- /dev/null +++ b/frontend/src/FullScreenDialog.css @@ -0,0 +1,45 @@ +.full-screen-dialog { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-color: var(--md-sys-color-surface-container); + z-index: 1; + animation: .1s show ease; +} + +.full-screen-dialog > .top-app-bar { + position: absolute; + top: 0; + right: 0; + left: 0; + display: flex; + align-items: center; + gap: .5rem; + padding: .5rem; +} + +.full-screen-dialog > .top-app-bar > * { + flex-shrink: 0; +} + +.full-screen-dialog > .top-app-bar > .title { + flex-grow: 1; + flex-shrink: 1; + color: var(--md-sys-color-on-surface); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +@keyframes show { + from { + opacity: 0; + scale: 0; + } + to { + opacity: 1; + scale: 1; + } +} diff --git a/frontend/src/FullScreenDialog.js b/frontend/src/FullScreenDialog.js new file mode 100644 index 0000000..155ea96 --- /dev/null +++ b/frontend/src/FullScreenDialog.js @@ -0,0 +1,28 @@ +import React, { useEffect, useState } from 'react' + +import '@material/web/iconbutton/icon-button.js' +import '@material/web/icon/icon.js' +import '@material/web/button/filled-button' + +import './FullScreenDialog.css' + +export default function ({ + editPoll, + setEditPoll, +}) { + // const [close, onClose] = useState(false) + return ( +
+
+ setEditPoll(false)}> + close + +
Изменить опрос
+ setEditPoll()}>Сохранить + + more_vert + +
+
+ ) +} diff --git a/frontend/src/PollList.css b/frontend/src/PollList.css new file mode 100644 index 0000000..a8188c6 --- /dev/null +++ b/frontend/src/PollList.css @@ -0,0 +1,4 @@ +.poll-list { + display: flex; + flex-direction: column; +} diff --git a/frontend/src/PollList.js b/frontend/src/PollList.js new file mode 100644 index 0000000..a7bcec9 --- /dev/null +++ b/frontend/src/PollList.js @@ -0,0 +1,37 @@ +import React, { useEffect, useState } from 'react' + +import PollListItem from "./PollListItem" +import FullScreenDialog from "./FullScreenDialog" + +import './PollList.css' + +const PollContext = React.createContext({ + polls: [], + fetchPolls: () => {}, +}) + +export default function PollList() { + const [polls, setPolls] = useState([]) + const [editPoll, setEditPoll] = useState(false) + + const fetchPolls = async () => { + const response = await fetch('/api/polls') + const polls = await response.json() + setPolls(polls) + } + + useEffect(() => { + fetchPolls() + }, []) + + return ( +
+ + {polls.map((poll) => ( + PollListItem(poll, setEditPoll) + ))} + + {editPoll ? : null} +
+ ) +} diff --git a/frontend/src/PollListItem.css b/frontend/src/PollListItem.css new file mode 100644 index 0000000..528d93a --- /dev/null +++ b/frontend/src/PollListItem.css @@ -0,0 +1,20 @@ +.poll-list-item { + position: relative; + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem; +} + +.poll-list-item .name { + color: var(--md-sys-color-on-surface); +} + +.poll-list-item .caption { + margin-top: .5rem; + color: var(--md-sys-color-on-surface-variant); +} + +md-switch { + margin-left: 1rem; +} diff --git a/frontend/src/PollListItem.js b/frontend/src/PollListItem.js new file mode 100644 index 0000000..d2a457a --- /dev/null +++ b/frontend/src/PollListItem.js @@ -0,0 +1,22 @@ +import '@material/web/switch/switch.js' + +import './PollListItem.css' + +export default function PollListItem(data, setEditPoll) { + return ( +
setEditPoll(true)}> + +
+
{data.name}
+
+ {data.days_of_week} +  •  + {data.time} +  •  + {data.question_number} +
+
+ +
+ ) +} diff --git a/frontend/src/index.css b/frontend/src/index.css index 57c3862..e22d5a4 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -1,3 +1,7 @@ +*:not(input, textarea, label) { + user-select: none; +} + body { margin: 0; scroll-behavior: smooth; diff --git a/frontend/src/index.js b/frontend/src/index.js index a1658e7..9f08a0c 100644 --- a/frontend/src/index.js +++ b/frontend/src/index.js @@ -1,13 +1,13 @@ -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import './index.css'; -import App from './App'; -import BottomNavBar from "./BottomNavBar"; +import React from 'react' +import ReactDOM from 'react-dom/client' +import './index.css' +import App from './App' +import BottomNavBar from "./BottomNavBar" -const root = ReactDOM.createRoot(document.getElementById('root')); +const root = ReactDOM.createRoot(document.getElementById('root')) root.render( -); +) diff --git a/web/main.py b/web/main.py index 8b47d87..17474d1 100644 --- a/web/main.py +++ b/web/main.py @@ -72,15 +72,49 @@ async def _(): ) -@app.websocket( - path='/ws/sync', +polls = [ + { + 'id': 1, + 'name': 'Текущее состояние сотрудников', + 'days_of_week': 'ПН-ПТ', + 'time': '11:00', + 'question_number': '1 вопрос', + }, + { + 'id': 2, + 'name': 'Планы на обед', + 'days_of_week': 'ПН-ПТ', + 'time': '11:45-12:00', + 'question_number': '2 вопроса', + }, +] + + +@app.get( + path='/api/polls', +) +async def _(): + return polls + + +@app.post( + path='/api/polls', ) async def _( - websocket: WebSocket, + poll: dict, ): - await connection_manager.connect(websocket) - try: - while True: - await connection_manager.broadcast(await websocket.receive_json()) - except WebSocketDisconnect: - connection_manager.disconnect(websocket) + polls.append(poll) + + +# @app.websocket( +# path='/ws/sync', +# ) +# async def _( +# websocket: WebSocket, +# ): +# await connection_manager.connect(websocket) +# try: +# while True: +# await connection_manager.broadcast(await websocket.receive_json()) +# except WebSocketDisconnect: +# connection_manager.disconnect(websocket)