diff --git a/changelog/_8878.md b/changelog/_8878.md
new file mode 100644
index 0000000000..14fd59244c
--- /dev/null
+++ b/changelog/_8878.md
@@ -0,0 +1,3 @@
+## Added
+
+- Added kiezradar 5 limit exceeded alert
diff --git a/meinberlin/react/kiezradar/EditKiezradar.jsx b/meinberlin/react/kiezradar/EditKiezradar.jsx
index b199a65158..7ca328c873 100644
--- a/meinberlin/react/kiezradar/EditKiezradar.jsx
+++ b/meinberlin/react/kiezradar/EditKiezradar.jsx
@@ -1,59 +1,31 @@
-import React, { useEffect, useState } from 'react'
+import React from 'react'
import django from 'django'
import { useParams } from 'react-router-dom'
import Kiezradar from './Kiezradar'
-import Loading from './Loading'
import { alert as Alert } from 'adhocracy4'
const editText = django.gettext('Edit')
const errorKiezText = django.gettext('Failed to fetch Kiez')
const errorText = django.gettext('Error')
-export default function EditKiezradar (props) {
+export default function EditKiezradar ({ kiezradars, ...props }) {
const { id } = useParams()
- const [kiezradar, setKiezradar] = useState([])
- const [loading, setLoading] = useState(false)
- const [error, setError] = useState(null)
-
- useEffect(() => {
- const fetchKiezradar = async () => {
- try {
- setLoading(true)
- setError(null)
-
- const response = await fetch(props.apiUrl + id)
-
- if (!response.ok) {
- throw new Error(errorKiezText)
- }
+ const kiezradar = kiezradars?.find(
+ (kiezradar) => kiezradar.id === parseInt(id, 10)
+ )
- const data = await response.json()
- setKiezradar(data)
- } catch (err) {
- setError(err.message)
- } finally {
- setLoading(false)
- }
- }
- fetchKiezradar()
- }, [])
+ if (!kiezradar) {
+ return (
+
+ )
+ }
return (
-
- {loading
- ?
- : error
- ? (
-
- )
- : (
- <>
-
{editText + ' ' + kiezradar.name}
-
- >
- )}
-
+ <>
+ {editText + ' ' + kiezradar.name}
+
+ >
)
}
diff --git a/meinberlin/react/kiezradar/Kiezradar.jsx b/meinberlin/react/kiezradar/Kiezradar.jsx
index 3cd148062e..a1d603e529 100644
--- a/meinberlin/react/kiezradar/Kiezradar.jsx
+++ b/meinberlin/react/kiezradar/Kiezradar.jsx
@@ -11,9 +11,6 @@ const nameYourKiezText = django.gettext('Name your Kiez selection')
const saveText = django.gettext('Save Kiez selection')
const savingText = django.gettext('Saving')
const errorText = django.gettext('Error')
-const errorLimitedExceededText = django.gettext(
- 'Users can only have up to 5 kiezradar filters. Delete a filter to create a new one.'
-)
const errorUpdateKiezText = django.gettext('Failed to update kiezradar filter')
const CENTRAL_BERLIN = [13.4050, 52.5200]
@@ -28,11 +25,17 @@ const defaultPoint = {
}
}
-export default function Kiezradar ({ kiezradar, onKiezradarSave, ...props }) {
+export default function Kiezradar ({
+ kiezradar,
+ apiUrl,
+ kiezradarFiltersUrl,
+ limitExceeded,
+ onKiezradarSave,
+ ...props
+}) {
const navigate = useNavigate()
const [loading, setLoading] = useState(false)
const [error, setError] = useState(null)
- const [limitExceeded, setLimitExceeded] = useState(false)
const [point, setPoint] = useState(kiezradar?.point ?? defaultPoint)
const [radius, setRadius] = useState(kiezradar?.radius ?? MIN_RADIUS)
@@ -52,23 +55,18 @@ export default function Kiezradar ({ kiezradar, onKiezradarSave, ...props }) {
point,
radius
}
- const url = props.apiUrl + (kiezradar ? kiezradar.id + '/' : '')
+ const url = apiUrl + (kiezradar ? kiezradar.id + '/' : '')
const method = kiezradar ? 'PATCH' : 'POST'
const response = await updateItem(payload, url, method)
const data = await response.json()
- if (data.non_field_errors) {
- setLimitExceeded(true)
- throw new Error(errorLimitedExceededText)
- }
-
if (!response.ok) {
throw new Error(errorUpdateKiezText)
}
onKiezradarSave(data)
- navigate(props.kiezradarFiltersUrl)
+ navigate(kiezradarFiltersUrl)
} catch (err) {
setError(err.message)
} finally {
@@ -115,7 +113,7 @@ export default function Kiezradar ({ kiezradar, onKiezradarSave, ...props }) {
diff --git a/meinberlin/react/kiezradar/KiezradarList.jsx b/meinberlin/react/kiezradar/KiezradarList.jsx
index d126d49ae3..a06c02e904 100644
--- a/meinberlin/react/kiezradar/KiezradarList.jsx
+++ b/meinberlin/react/kiezradar/KiezradarList.jsx
@@ -9,7 +9,6 @@ const noSavedKiezradarsText = django.gettext('No saved Kiezes')
const addKiezText = django.gettext('Add Kiez')
const yourKiezradarsText = django.gettext('Your Kiezes')
const errorText = django.gettext('Error')
-const errorKiezesText = django.gettext('Failed to fetch Kiezes')
const errorDeleteKiezesText = django.gettext(
'Failed to delete kiezradar'
)
@@ -30,36 +29,14 @@ export default function KiezradarList ({
planListUrl,
kiezradarFiltersUrl,
kiezradarNewUrl,
+ kiezradars,
+ limitExceeded,
onKiezradarDelete
}) {
- const [kiezradars, setKiezradars] = useState([])
const [loading, setLoading] = useState(false)
const [error, setError] = useState(null)
const [deleteModal, setDeleteModal] = useState(null)
- useEffect(() => {
- const fetchKiezradars = async () => {
- try {
- setLoading(true)
- setError(null)
-
- const response = await fetch(apiUrl)
-
- if (!response.ok) {
- throw new Error(errorKiezesText)
- }
-
- const data = await response.json()
- setKiezradars(data)
- } catch (err) {
- setError(err.message)
- } finally {
- setLoading(false)
- }
- }
- fetchKiezradars()
- }, [])
-
const handleDelete = async (kiezradar) => {
try {
setLoading(true)
@@ -71,10 +48,6 @@ export default function KiezradarList ({
throw new Error(errorDeleteKiezesText)
}
- setKiezradars((prevKiezradars) =>
- prevKiezradars.filter((prevKiezradar) => prevKiezradar.id !== kiezradar.id)
- )
-
onKiezradarDelete(kiezradar)
} catch (err) {
setError(err.message)
@@ -157,12 +130,19 @@ export default function KiezradarList ({
-
- {addKiezText}
-
+ {limitExceeded
+ ? (
+
+ )
+ : (
+
+ {addKiezText}
+ )}
>
)}
diff --git a/meinberlin/react/kiezradar/Kiezradars.jsx b/meinberlin/react/kiezradar/Kiezradars.jsx
index 1ffcacafd6..78e9783e96 100644
--- a/meinberlin/react/kiezradar/Kiezradars.jsx
+++ b/meinberlin/react/kiezradar/Kiezradars.jsx
@@ -1,10 +1,11 @@
-import React, { useState } from 'react'
+import React, { useEffect, useState } from 'react'
import django from 'django'
import KiezradarList from './KiezradarList'
import { Route, Routes, useLocation, Link } from 'react-router-dom'
import NewKiezradar from './NewKiezradar'
import EditKiezradar from './EditKiezradar'
-import { alert as A4Alert, classNames } from 'adhocracy4'
+import { alert as Alert, classNames } from 'adhocracy4'
+import Loading from './Loading'
const translations = {
titleText: django.gettext('Kiez selection'),
@@ -34,105 +35,176 @@ const translations = {
django.gettext('%(title)s has been permanently deleted.'),
{ title },
true
- )
+ ),
+ errorKiezesText: django.gettext('Failed to fetch Kiezes'),
+ limitExceededText: django.gettext('You’ve reached the maximum number of 5 Kiez allowed. To save a new one, you’ll need to delete an existing Kiez.')
}
export default function Kiezradars (props) {
+ const [loading, setLoading] = useState(false)
+ const [kiezradars, setKiezradars] = useState([])
+ const [error, setError] = useState(null)
const [alert, setAlert] = useState(null)
const location = useLocation()
const isNewKiez = location.pathname.includes(props.kiezradarNewUrl)
+ useEffect(() => {
+ const fetchKiezradars = async () => {
+ try {
+ setLoading(true)
+ setError(null)
+
+ const response = await fetch(props.apiUrl)
+
+ if (!response.ok) {
+ throw new Error(translations.errorKiezesText)
+ }
+
+ const data = await response.json()
+ setKiezradars(data)
+ } catch (err) {
+ setError(err.message)
+ } finally {
+ setLoading(false)
+ }
+ }
+ fetchKiezradars()
+ }, [])
+
const handleAlert = ({ title, message }) => {
setAlert({ title, message })
window.scrollTo({ top: 0, behavior: 'smooth' })
}
+ const limitExceeded = kiezradars.length === 5
+
return (
<>
+ {error && (
+ setError(null)}
+ />
+ )}
{alert && (
setAlert(null)}
+ onClick={() => setAlert(null)}
/>
)}
+ {limitExceeded && (
+
+ )}
{translations.titleText}
{translations.descriptionText}
-
-
-
-
- handleAlert({
- message: translations.kiezDeletedText(kiezradar.name)
- })}
- />
- }
- />
-
- handleAlert({
- message: translations.kiezCreatedText(kiezradar.name)
- })}
- />
- }
- />
-
- handleAlert({
- message: translations.kiezSavedText(kiezradar.name)
- })}
- />
- }
- />
-
+
+ {loading
+ ?
+ : (
+
+
+
+ {
+ setKiezradars((prevKiezradars) => prevKiezradars.filter((prevKiezradar) => prevKiezradar.id !== kiezradar.id))
+
+ handleAlert({
+ message: translations.kiezDeletedText(kiezradar.name)
+ })
+ }}
+ />
+ }
+ />
+ {
+ setKiezradars((prevKiezradars) =>
+ [...prevKiezradars, kiezradar]
+ )
+
+ handleAlert({
+ message: translations.kiezCreatedText(kiezradar.name)
+ })
+ }}
+ />
+ }
+ />
+ {
+ setKiezradars((prevKiezradars) =>
+ prevKiezradars.map((item) =>
+ item.id === kiezradar.id ? kiezradar : item
+ )
+ )
+
+ handleAlert({
+ message: translations.kiezSavedText(kiezradar.name)
+ })
+ }}
+ />
+ }
+ />
+
+
)}
>
)
}
-function Alert ({ message, onClose }) {
+function AlertLimit () {
+ const [active, isActive] = useState(true)
+
+ if (!active) {
+ return null
+ }
+
return (
-
onClose()}
+ isActive(false)}
/>
)
}