Skip to content

Commit

Permalink
project-tiles: adapt ui states for ended and upcoming projects as wel…
Browse files Browse the repository at this point in the history
…l as plans
  • Loading branch information
vellip committed Jan 14, 2025
1 parent b68fe82 commit 4b98e96
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 26 deletions.
3 changes: 3 additions & 0 deletions changelog/8573.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### Added
- UI states for upcoming and ending projects on project tiles
- adapted UI for plan tiles
13 changes: 10 additions & 3 deletions meinberlin/assets/scss/components_user_facing/_project-tile.scss
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,17 @@ a.project-tile {

.project-tile__status {
margin-top: auto;
margin-bottom: .5em;
font-size: $font-size-sm;
color: $text-base;
}

.project-tile__status__bar {
width: 100%;
height: .3em;
appearance: none;
background: $message-light-green;
border: none;
margin-bottom: .5em;

&::-moz-progress-bar {
background: $primary;
Expand All @@ -118,7 +123,9 @@ a.project-tile {
}

.project-tile__timespan {
font-size: $font-size-sm;
font-weight: 400;
color: $text-base;
}

.project-tile__plan__count {
margin-right: .25em;
}
71 changes: 50 additions & 21 deletions meinberlin/react/projects/ProjectTile.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
/* global django */
import React, { useId } from 'react'
import { classNames } from '../contrib/helpers'
import ProjectTopics from './ProjectTopics'
import { classNames, toLocaleDate } from '../contrib/helpers'
import ProjectTilePills from './ProjectTopics'
import getTimespan from './get-timespan'
import ImageWithPlaceholder from '../contrib/ImageWithPlaceholder'

const copyrightMissingStr = django.gettext('copyright missing')
const copyrightStr = django.gettext('copyright by')
const altImgStr = django.gettext('Here you can find a decorative picture.')
const participationEndedStr = django.gettext('Participation ended.')
const beginsOnStr = django.gettext('Begins on the')
const participationProjectsStr = django.gettext('Participation projects')
const participationProjectStr = django.gettext('Participation project')

function truncateText (item) {
if (item.length > 170) {
Expand All @@ -22,6 +26,16 @@ const ProjectTile = ({ project, isHorizontal, topicChoices, isMapTile }) => {
const describedById = useId()
const statusId = useId()
const statusBarProgress = project.active_phase ? project.active_phase[0] + '%' : null
let state = 'past'

// Plans are always active since we dont change state for them, we only show
// projects belonging to them.
if (project.active_phase || project.type === 'plan') {
state = 'active'
} else if (project.future_phase) {
state = 'future'
}
console.log(project)

return (
<a
Expand Down Expand Up @@ -51,7 +65,7 @@ const ProjectTile = ({ project, isHorizontal, topicChoices, isMapTile }) => {
{!isMapTile && <span className="project-tile__head">{project.district}</span>}
{project.topics?.length > 0 &&
<div className="project-tile__topics">
<ProjectTopics project={project} topicChoices={topicChoices} />
<ProjectTilePills project={project} topicChoices={topicChoices} />
</div>}
<h3 className="project-tile__title" id={labelId}>{project.title}</h3>
{project.description && !isMapTile && (
Expand All @@ -60,24 +74,39 @@ const ProjectTile = ({ project, isHorizontal, topicChoices, isMapTile }) => {
</p>
)}

{project.active_phase &&
<>
<progress
value={project.active_phase[0]}
max="100"
aria-valuenow={project.active_phase[0]}
aria-valuemin="0"
aria-valuemax="100"
className="project-tile__status"
id={statusId}
>
{statusBarProgress}
</progress>
<label htmlFor={statusId} className="project-tile__timespan">
<i className="far fa-clock" aria-hidden="true" />
{getTimespan(project)}
</label>
</>}
<div className="project-tile__status">
{state === 'active' && project.type !== 'plan' && (
<>
<progress
value={project.active_phase[0]}
max="100"
aria-valuenow={project.active_phase[0]}
aria-valuemin="0"
aria-valuemax="100"
id={statusId}
className="project-tile__status__bar"
>
{statusBarProgress}
</progress>
<label htmlFor={statusId} className="project-tile__timespan">
<i className="far fa-clock" aria-hidden="true" />
{getTimespan(project)}
</label>
</>
)}
{state === 'active' && project.type === 'plan' && (
<p>
<i className="fas fa-table-cells" aria-hidden="true" />

<span className="project-tile__plan__count">{project.published_projects_count}</span>
{project.published_projects_count === 1
? participationProjectStr
: participationProjectsStr}
</p>
)}
{state === 'past' && <p>{participationEndedStr}</p>}
{state === 'future' && <p>{beginsOnStr} {toLocaleDate(project.future_phase, undefined, { month: 'numeric', year: 'numeric', day: 'numeric' })}</p>}
</div>
</div>
</a>
)
Expand Down
13 changes: 11 additions & 2 deletions meinberlin/react/projects/ProjectTopics.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
import django from 'django'
import React from 'react'

const ProjectTopics = ({ project, topicChoices }) => {
const planStr = django.gettext('Plan')

const ProjectTilePills = ({ project, topicChoices }) => {
const topicList = project.topics.map((val) => {
return topicChoices[val]
})

if (project.type === 'plan' && topicList.length > 1) {
const additionalPills = topicList.length - 1
topicList.splice(1, additionalPills, '+1')
}

if (project.topics && project.topics.length > 0) {
return (
<ul className="pill__list pill__list--inline">
{project.type === 'plan' && <li className="pill pill--label">{planStr}</li>}
{topicList.map(topic =>
<li key={topic} className="pill pill--topic">{topic}</li>
)}
Expand All @@ -16,4 +25,4 @@ const ProjectTopics = ({ project, topicChoices }) => {
}
}

export default ProjectTopics
export default ProjectTilePills

0 comments on commit 4b98e96

Please sign in to comment.