From 58831ecb2455ddf3fa4c45fff7840740f885a38b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nina=20Dr=C3=BCke?= Date: Sat, 6 Jan 2024 19:01:41 +0100 Subject: [PATCH] feat: topic data structure --- src/components/Category.tsx | 184 +++++---- src/components/Quote.tsx | 17 +- src/components/quote.module.scss | 8 +- src/data.ts | 626 +++++++++++++++++++++++++++++-- src/pages/index.tsx | 99 +++-- src/types.ts | 21 +- 6 files changed, 785 insertions(+), 170 deletions(-) diff --git a/src/components/Category.tsx b/src/components/Category.tsx index 8340ead..f8cadb0 100644 --- a/src/components/Category.tsx +++ b/src/components/Category.tsx @@ -2,119 +2,137 @@ import { Dispatch, SetStateAction } from 'react'; import styles from '@/components/category.module.scss'; interface Props { - label: string; + name: string; description: string; - quotes: { title: string; id: number }[]; + topics: Topic[]; id: number; - quoteCount: number; - selected: { id: number; categoryId: number } | undefined; - setSelected: Dispatch< - SetStateAction<{ id: number; categoryId: number } | undefined> - >; + subjectCount: number; + setSelectedTopic: Dispatch>; } export default function Category({ - label, + name, description, - quotes, + topics, id, - quoteCount, - selected, - setSelected, + subjectCount, + setSelectedTopic, }: Props) { const index = id - 1; const degree = index * 36; - const quotedegrees = (cirle: 'outer' | 'inner', quoteId: number) => { + const radius = (cirle: 'outer' | 'inner', subId: number) => { if (cirle === 'outer') { - return (50 / quoteCount) * quoteId; + return (46 / subjectCount) * subId; } if (cirle === 'inner') { - return (50 / quoteCount) * (quoteId - 1); + return (46 / subjectCount) * (subId - 1); } }; return ( - {quotes.map((quote) => ( - - - + {topics.map((top) => { + return ( + + + + + + + + + + - - - - - - + + setSelectedTopic(top)} + /> - {/* */} - setSelected({ id: quote.id, categoryId: id })} - /> - - ))} + + + {top.title} + + + + ); + })} - - {label} + + + + + + {name} + diff --git a/src/components/Quote.tsx b/src/components/Quote.tsx index 98d1c3a..6eb5b36 100644 --- a/src/components/Quote.tsx +++ b/src/components/Quote.tsx @@ -2,11 +2,11 @@ import Close from '@/assets/icons/Close'; import styles from '@/components/quote.module.scss'; interface Props { - title?: string; - text?: string; + title: string; + quotes: string[]; onClose: () => void; } -export default function Quote({ title, text, onClose }: Props) { +export default function Quote({ title, quotes, onClose }: Props) { return (
@@ -19,7 +19,16 @@ export default function Quote({ title, text, onClose }: Props) {
-

{text}

+
+ {quotes.map((quote, index) => ( +

+ "{quote}" +

+ ))} +
); diff --git a/src/components/quote.module.scss b/src/components/quote.module.scss index 59de74c..56ddeae 100644 --- a/src/components/quote.module.scss +++ b/src/components/quote.module.scss @@ -22,7 +22,7 @@ @media screen and (min-width: 400px) { width: auto; - max-width: 368px; + max-width: 420px; padding: 24px; } @@ -54,6 +54,12 @@ } } } + + &__content { + &__quote { + font-size: 20px; + } + } } } diff --git a/src/data.ts b/src/data.ts index 569f799..9b5f1ba 100644 --- a/src/data.ts +++ b/src/data.ts @@ -2,63 +2,613 @@ export const categories: Category[] = [ { id: 1, name: 'Kritik', - description: 'Kritik beschreibt Aspekte im Viertel, die beanstandet oder bemängelt wurden.', - quotes: [ - { id: 1, title: 'Quote 1', text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.' }, - { id: 2, title: 'Quote 2', text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.' }, - ], + description: + 'Kritik beschreibt Aspekte im Viertel, die beanstandet oder bemängelt wurden.', }, { id: 2, name: 'Potentiale', description: '', - quotes: [ - { id: 1, title: 'Quote 1', text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.' }, - { id: 2, title: 'Quote 2', text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.' }, - { id: 3, title: 'Quote 3', text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.' }, - { id: 4, title: 'Quote 4', text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.' }, - ], }, { id: 3, name: 'Konfliktfelder', description: '', - quotes: [{ id: 1, title: 'Quote 1', text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.' }], }, { id: 4, name: 'Anerkennung', - description: 'Anerkennung beschreibt im Viertel wahrgenommene As-pekte, die bereits zum Gemeinwohl beitragen.', - quotes: [{ id: 1, title: 'Quote 1', text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.' }], + description: + 'Anerkennung beschreibt im Viertel wahrgenommene As-pekte, die bereits zum Gemeinwohl beitragen.', }, { id: 5, name: 'Erfordernisse', - description: 'Erfordernisse beschreibt im Viertel wahrgenommene Vor-aussetzungen, die als notwendig erachtet werden, um zum Gemeinwohl beizutragen.', - quotes: [ - { id: 1, title: 'Quote 1', text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.' }, - { id: 2, title: 'Quote 2', text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.' }, - { id: 3, title: 'Quote 3', text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.' }, - ], + description: + 'Erfordernisse beschreibt im Viertel wahrgenommene Vor-aussetzungen, die als notwendig erachtet werden, um zum Gemeinwohl beizutragen.', }, ]; - -export const aims = [ - 'Klimapositivität', - 'Sauberkeit', - 'Verkehr', - 'Nachhaltigkeit', - 'Bildung', - 'Gerechtigkeit', - 'Inklusion', - 'Wohnen', - 'Erholung', - 'Grünflächen', - 'Kunst und Kultur', - 'Begegnungsorte', - 'Älter werden im Viertel', - 'Nachbar:innenschaft', - 'Gesundheit', - 'Vernetzung', +export const aims: Aim[] = [ + { + name: 'Klimapositivität', + topics: [ + { + categoryId: 1, + id: 1, + title: 'Bepflanzung', + quotes: [ + 'Es gibt zu wenig Bäume meiner Meinung nach. Und zu wenig Grünflächen.', + 'An sich gibt es oder gab es in den Innenhöfen immer Gärten. Zum Teil sind die zugepflastert worden.', + ], + }, + { + categoryId: 2, + id: 1, + title: 'Begrünung', + quotes: [ + 'Es gibt auch noch Vorgärten in den Querstraßen zum Teil. In den kleinen Straßen hier im Viertel. Schön sind natürlich auch die Alleen. Der Hansaplatz ist auch schön grün. Es könnte mehr sein.', + 'Die Begrünung der Fassaden ist ein Trend. Da gibt es ja auch Ideen, von daher müsste man da jetzt noch richtig investieren.', + ], + }, + { + categoryId: 2, + id: 2, + title: 'Verwendung von Regenwasser', + quotes: [ + 'Ich weiß, dass das machbar ist, Regenwasser zu verwenden. Weil ich Klempner bin, weiß ich, dass es da gute Möglichkeiten gibt. Aber das liegt dann nicht an den Mietern, sondern an den Vermietern.', + ], + }, + { + categoryId: 3, + title: 'Vernetzung mit Klimabezug', + id: 1, + quotes: [ + 'It is so nice that we can organize some stuff together and talk about important issues and climate. And sometimes I download “Na dann?”and there is an app that connects you with your neighborhood. So I am connected to that as well. Sometimes they gather and we do yoga and talk about how we could be more sustainable or separate the trash and sometimes we find important things and remind everyone to separate their trash. We show all the respect.', + 'Ich weiß, dass es ein Projekt gibt: die Wassertanke. Davon habe ich schonmal gehört. Ich glaube das ist zwar nicht für Regenwasser, aber die Stadt Münster verteilt doch immer diese grünen Säcke, aber bei der Wassertanke ist die Idee, dass die Menschen mit der Gießkanne kommen.', + ], + }, + { + categoryId: 4, + id: 1, + title: 'Eigeninitiative', + quotes: [ + 'Aber insgesamt wird sich Mühe gegeben. Auch vor unserem Haus, da ist ein kleiner Garten mit schönen Pflanzen. Das ist zwar nicht so eine große Grünflache, aber man bemüht sich auf dem kleinen Raum, den man hat, es grün zu machen.', + ], + }, + { + categoryId: 5, + id: 1, + title: 'Raumkonflikt mit Verkehrsnutzung', + quotes: [ + 'An sich gibt es oder gab es hier in den Innenhöfen auch immer wieder Gärten. Zum Teil sind die leider zugepflastert worden. Das ist in der Querstraße, gerade in den letzten 10 Jahren, dass das zugenommen hat, dass da Parkplätze geschaffen werden und dann wird gepflastert.', + ], + }, + ], + }, + { + name: 'Sauberkeit', + topics: [ + { + categoryId: 1, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 2, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 3, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 4, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 5, + id: 1, + title: '', + quotes: [''], + }, + ], + }, + { + name: 'Verkehr', + topics: [ + { + categoryId: 1, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 2, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 3, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 4, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 5, + id: 1, + title: '', + quotes: [''], + }, + ], + }, + { + name: 'Nachhaltigkeit', + topics: [ + { + categoryId: 1, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 2, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 3, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 4, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 5, + id: 1, + title: '', + quotes: [''], + }, + ], + }, + { + name: 'Bildung', + topics: [ + { + categoryId: 1, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 2, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 3, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 4, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 5, + id: 1, + title: '', + quotes: [''], + }, + ], + }, + { + name: 'Gerechtigkeit', + topics: [ + { + categoryId: 1, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 2, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 3, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 4, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 5, + id: 1, + title: '', + quotes: [''], + }, + ], + }, + { + name: 'Inklusion', + topics: [ + { + categoryId: 1, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 2, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 3, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 4, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 5, + id: 1, + title: '', + quotes: [''], + }, + ], + }, + { + name: 'Wohnen', + topics: [ + { + categoryId: 1, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 2, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 3, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 4, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 5, + id: 1, + title: '', + quotes: [''], + }, + ], + }, + { + name: 'Erholung', + topics: [ + { + categoryId: 1, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 2, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 3, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 4, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 5, + id: 1, + title: '', + quotes: [''], + }, + ], + }, + { + name: 'Grünflächen', + topics: [ + { + categoryId: 1, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 2, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 3, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 4, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 5, + id: 1, + title: '', + quotes: [''], + }, + ], + }, + { + name: 'Kunst und Kultur', + topics: [ + { + categoryId: 1, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 2, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 3, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 4, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 5, + id: 1, + title: '', + quotes: [''], + }, + ], + }, + { + name: 'Begegnungsorte', + topics: [ + { + categoryId: 1, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 2, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 3, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 4, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 5, + id: 1, + title: '', + quotes: [''], + }, + ], + }, + { + name: 'Älter werden im Viertel', + topics: [ + { + categoryId: 1, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 2, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 3, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 4, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 5, + id: 1, + title: '', + quotes: [''], + }, + ], + }, + { + name: 'Nachbar:innenschaft', + topics: [ + { + categoryId: 1, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 2, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 3, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 4, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 5, + id: 1, + title: '', + quotes: [''], + }, + ], + }, + { + name: 'Gesundheit', + topics: [ + { + categoryId: 1, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 2, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 3, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 4, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 5, + id: 1, + title: '', + quotes: [''], + }, + ], + }, + { + name: 'Vernetzung', + topics: [ + { + categoryId: 1, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 2, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 3, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 4, + id: 1, + title: '', + quotes: [''], + }, + { + categoryId: 5, + id: 1, + title: '', + quotes: [''], + }, + ], + }, ]; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 010e4f4..b33368e 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -2,37 +2,66 @@ import styles from './index.module.scss'; import Aim from '@/components/Aim'; import Category from '@/components/Category'; import Quote from '@/components/Quote'; -import { useEffect, useState } from 'react'; +import { use, useCallback, useEffect, useState } from 'react'; import { aims, categories } from '@/data'; -const quoteCount = categories.sort( - (a, b) => b.quotes.length - a.quotes.length -)[0].quotes.length; +export default function App() { + const [selectedAimId, setSelectedAimId] = useState(0); + const [selectedAim, setSelectedAim] = useState(aims[0]); + const [selectedTopicId, setSelectedTopicId] = useState(); + const [selectedTopic, setSelectedTopic] = useState(); -console.log(quoteCount); + const [subjectCount, setTopicCount] = useState(0); -categories.sort((a, b) => a.id - b.id); + const findTopicsPerCategory = useCallback( + (catId: number) => { + let foundtopics: Topic[] = []; -export default function App() { - const [selectedQuoteId, setSelectedQuoteId] = useState< - { id: number; categoryId: number } | undefined - >(); - const [selectedAimId, setSelectedAimId] = useState(0); - const [selectedQuote, setSelectedQuote] = useState< - { id: number; title: string; text: string } | undefined - >(); + selectedAim.topics.map((top) => { + if (top.categoryId === catId) { + foundtopics.push(top); + } + }); + + return foundtopics; + }, + [selectedAim.topics] + ); + + const findMaxTopicCount = useCallback(() => { + let max = 1; + + for (let i = 1; i <= 5; i++) { + let currMax = findTopicsPerCategory(i).length; + + if (currMax > max) { + max = currMax; + } + } + + return max; + }, [findTopicsPerCategory]); useEffect(() => { - if (!selectedQuoteId) return; + let foundAim = aims.find((aim, index) => index === selectedAimId); - const selectedCategory = categories.find( - (category) => category.id === selectedQuoteId?.categoryId - ); + if (foundAim) { + setSelectedAim(foundAim); - setSelectedQuote( - selectedCategory?.quotes.find((quote) => quote.id === selectedQuoteId?.id) + setTopicCount(findMaxTopicCount()); + } + }, [selectedAimId, findMaxTopicCount]); + + useEffect(() => { + setSelectedTopic( + aims + .find((aim, index) => index === selectedAimId) + ?.topics.find((top, index) => { + const foundIndex = index === selectedTopic?.id; + return foundIndex; + }) ); - }, [selectedQuoteId]); + }, [selectedAimId, selectedTopic]); return (
@@ -45,18 +74,16 @@ export default function App() { height="50%" > {categories.map((category, index) => { - const sorted = category.quotes.sort((a, b) => b.id - a.id); - console.log(category.id, sorted); - return ( b.id - a.id)} + topics={findTopicsPerCategory(category.id).sort( + (a, b) => b.id - a.id + )} id={category.id} - quoteCount={quoteCount} - selected={selectedQuoteId} - setSelected={setSelectedQuoteId} + subjectCount={subjectCount} + setSelectedTopic={setSelectedTopic} key={index} /> ); @@ -81,7 +108,7 @@ export default function App() { > {aims.map((aim, index) => ( - Gemeinwohl- + Quartiers- - quartiers- + gemeinwohl- index @@ -108,11 +135,11 @@ export default function App() {
- {selectedQuoteId && ( + {selectedTopic && ( setSelectedQuoteId(undefined)} + title={selectedTopic.title} + quotes={selectedTopic.quotes} + onClose={() => setSelectedTopic(undefined)} /> )} diff --git a/src/types.ts b/src/types.ts index 0f8e2ad..5ffaba6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,12 +1,17 @@ -interface Quote { - id: number; - title: string; - text: string; -} - interface Category { id: number; name: string; description: string; - quotes: Quote[]; -} \ No newline at end of file +} + +interface Aim { + name: string; + topics: Topic[]; +} + +interface Topic { + categoryId: number; + id: number; + title: string; + quotes: string[]; +}