From d2ab3c0727ab9077daa207aebda039734774f867 Mon Sep 17 00:00:00 2001 From: Sev Furneaux Date: Tue, 19 Nov 2024 09:46:44 +0000 Subject: [PATCH] react/livequestions: style statistics --- changelog/_8546.md | 6 + .../_live_questions.scss | 25 +++ .../react/livequestions/QuestionBox.jsx | 2 +- .../react/livequestions/StatisticsBox.jsx | 188 +++++++++--------- .../react_questions_statistics.jsx | 13 -- 5 files changed, 122 insertions(+), 112 deletions(-) create mode 100644 changelog/_8546.md delete mode 100644 meinberlin/react/livequestions/react_questions_statistics.jsx diff --git a/changelog/_8546.md b/changelog/_8546.md new file mode 100644 index 0000000000..630b9337da --- /dev/null +++ b/changelog/_8546.md @@ -0,0 +1,6 @@ +### Removed +- Removed react_questions_statistics.jsx + +### Changed + +- Style `StatisticsBox` diff --git a/meinberlin/assets/scss/components_user_facing/_live_questions.scss b/meinberlin/assets/scss/components_user_facing/_live_questions.scss index 8d5e98ac9c..71663bb5e4 100644 --- a/meinberlin/assets/scss/components_user_facing/_live_questions.scss +++ b/meinberlin/assets/scss/components_user_facing/_live_questions.scss @@ -7,3 +7,28 @@ margin-left: auto; margin-bottom: .625em; } + +.live-question__progress { + display: flex; + gap: 8px; + margin-bottom: 8px; + position: relative; +} + +.live-question__progress-bar { + background-color: $gray-lighter; + border-radius: 10px; + height: 100%; + position: absolute; + z-index: 0; +} + +.live-question__progress-text { + padding: 0 0.5rem; + position: relative; + z-index: 1; +} + +.live-question__progress-percentage { + font-weight: bold; +} \ No newline at end of file diff --git a/meinberlin/react/livequestions/QuestionBox.jsx b/meinberlin/react/livequestions/QuestionBox.jsx index 9fcf9ed36c..1f5affad3d 100644 --- a/meinberlin/react/livequestions/QuestionBox.jsx +++ b/meinberlin/react/livequestions/QuestionBox.jsx @@ -249,7 +249,7 @@ export default class QuestionBox extends React.Component { : } diff --git a/meinberlin/react/livequestions/StatisticsBox.jsx b/meinberlin/react/livequestions/StatisticsBox.jsx index 8baf0b4339..a5c1f4726d 100644 --- a/meinberlin/react/livequestions/StatisticsBox.jsx +++ b/meinberlin/react/livequestions/StatisticsBox.jsx @@ -1,35 +1,35 @@ import django from 'django' import { updateItem } from '../contrib/helpers.js' -import React from 'react' +import React, { useState, useEffect } from 'react' import QuestionUser from './QuestionUser' import QuestionModerator from './QuestionModerator' -export default class StatisticsBox extends React.Component { - constructor (props) { - super(props) - this.state = { answeredQuestions: props.answeredQuestions } - } +const questionAnsweredTag = django.gettext('Questions Answered') +const categoriesTag = django.gettext('Categories') +const categoriesAnsweredTag = django.gettext('Affiliation Of Answered Questions') - UNSAFE_componentWillReceiveProps (props) { - this.setState({ answeredQuestions: props.answeredQuestions }) - } +function StatisticsBox (props) { + const [answeredQuestions, setAnsweredQuestions] = useState(props.answeredQuestions) - updateQuestion (data, id) { - const url = this.props.questions_api_url + id + '/' + useEffect(() => { + setAnsweredQuestions(props.answeredQuestions) + }, [props.answeredQuestions]) + + const updateQuestion = (data, id) => { + const url = props.questions_api_url + id + '/' return updateItem(data, url, 'PATCH') } - removeFromList (id, data) { - this.updateQuestion(data, id) - .then(response => this.setState(prevState => ({ - answeredQuestions: prevState.answeredQuestions.filter(question => question.id !== id) - }))) + const removeFromList = (id, data) => { + updateQuestion(data, id) + .then(() => setAnsweredQuestions(prevQuestions => prevQuestions.filter(question => question.id !== id) + )) } - countCategory (category) { + const countCategory = (category) => { let countPerCategory = 0 let answeredQuestions = 0 - this.props.answeredQuestions.forEach(function (question) { + props.answeredQuestions.forEach(function (question) { if (question.is_answered && !question.is_hidden) { answeredQuestions++ if (question.category === category) { @@ -40,86 +40,78 @@ export default class StatisticsBox extends React.Component { return Math.round(countPerCategory * 100 / answeredQuestions) || 0 } - render () { - const questionAnsweredTag = django.gettext('Questions Answered') - const categoriesAnsweredTag = django.gettext('Affiliation Of Answered Questions') - - return ( -
-
-
- {this.props.categories.length > 0 && -
-

{categoriesAnsweredTag}

-
- {this.props.categories.map((category, index) => { - const countPerCategory = this.countCategory(category) - const style = { width: countPerCategory + '%' } - return ( -
-
-
-  {category} {countPerCategory}% -
-
- ) - })} + return ( +
+ {Object.keys(props.category_dict).length > 0 && ( + <> +

{categoriesAnsweredTag}

+
+

{categoriesTag}

+ {Object.keys(props.category_dict).map((id) => { + const countPerCategory = countCategory(props.category_dict[id]) + const style = { width: countPerCategory + '%' } + return ( +
+
+
+ + {countPerCategory}% + {' '} + {props.category_dict[id]} +
-
} -

{questionAnsweredTag}

- {this.props.isModerator - ? ( -
- {this.state.answeredQuestions.map((question, index) => { - return ( - - {question.text} - - ) - })} -
- ) - : ( -
- {this.state.answeredQuestions.map((question, index) => { - return ( - - {question.text} - - ) - })} -
- )} + ) + })}
-
-
- ) - } + + )} +

+ {questionAnsweredTag} ({answeredQuestions.length}) +

+ {props.isModerator + ? answeredQuestions.map((question) => ( + + {question.text} + + )) + : answeredQuestions.map((question) => ( + + {question.text} + + ))} +
+ ) } + +export default StatisticsBox diff --git a/meinberlin/react/livequestions/react_questions_statistics.jsx b/meinberlin/react/livequestions/react_questions_statistics.jsx deleted file mode 100644 index 19fe0969d7..0000000000 --- a/meinberlin/react/livequestions/react_questions_statistics.jsx +++ /dev/null @@ -1,13 +0,0 @@ -import StatisticsBox from './StatisticsBox' -import React from 'react' -import { createRoot } from 'react-dom/client' - -export function renderData (el) { - const props = JSON.parse(el.getAttribute('data-attributes')) - const root = createRoot(el) - root.render( - - - - ) -}