Skip to content

Commit

Permalink
Survey: update survey structure, create radnetz-brandenburg config (#102
Browse files Browse the repository at this point in the history
)
  • Loading branch information
JohannaPeanut authored May 22, 2024
2 parents b73bb57 + e8e2d36 commit 619919f
Show file tree
Hide file tree
Showing 58 changed files with 2,845 additions and 488 deletions.
4 changes: 4 additions & 0 deletions public/logo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

## Logo for public survey BB

The logo `bb-logo.png` in this folder is referenced in `/survey-public/radnetz-brandenburg/data/survey.ts`. Typically, we source logos directly from the public websites of the respective cycle highways. However, in this particular instance, no public website exists. Therefore, we have stored the logo in this repository.
Binary file added public/logo/bb-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 46 additions & 0 deletions src/core/styles/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,49 @@
.stripe-background {
background: repeating-linear-gradient(-45deg, #da1616, #da1616 2px, white 2px, white 4px);
}
.stripe-background-vertical-orange {
background: repeating-linear-gradient(
-90deg,
#f58f9e,
#f58f9e 3px,
transparent 2px,
transparent 6px
);
}

.stripe-background-vertical-darkblue {
background: repeating-linear-gradient(
-90deg,
#1353d1,
#1353d1 3px,
transparent 2px,
transparent 6px
);
}
.stripe-background-vertical-lightblue {
background: repeating-linear-gradient(
-90deg,
#9ebaf4,
#9ebaf4 3px,
transparent 2px,
transparent 6px
);
}
.stripe-background-vertical-blue {
background: repeating-linear-gradient(
-90deg,
#009ae9,
#009ae9 3px,
transparent 2px,
transparent 6px
);
}
.stripe-background-vertical-purple {
background: repeating-linear-gradient(
-90deg,
#ab7de3,
#ab7de3 3px,
transparent 2px,
transparent 6px
);
}
48 changes: 21 additions & 27 deletions src/pages/[projectSlug]/surveys/[surveyId]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,21 +96,29 @@ export const Survey = () => {
)
: surveyDefinitionArrayWithLatestQuestions

const groupedSurveyResponseData = rawData.map((r) => {
const questionId = Object.keys(r)[0]
const question = surveyDefinitionArray.find((question) => Number(questionId) === question.id)

if (!question || !questionId) return
const response = r[questionId]
if (!response) return
const groupedSurveyResponseData = rawData
.map((r) => {
const questionId = Object.keys(r)[0]
const question = surveyDefinitionArray.find((question) => Number(questionId) === question.id)

if (
!question ||
!questionId ||
// only multiple and single response questions are supported
!(question.component === "singleResponse" || question.component === "multipleResponse")
)
return
const response = r[questionId]
if (!response) return

const data = Object.entries(response).map(([key, value]) => ({
name: question?.props?.responses?.find((r) => r.id === Number(key))?.text ?? "Missing name",
value,
}))
const data = Object.entries(response).map(([key, value]) => ({
name: question?.props?.responses?.find((r) => r.id === Number(key))?.text ?? "Missing name",
value,
}))

return { questionLabel: question.label, data }
})
return { questionLabel: question.label, data }
})
.filter(Boolean)

const handleCopyChartDataButtonClick = async () => {
await navigator.clipboard.writeText(JSON.stringify(groupedSurveyResponseData))
Expand Down Expand Up @@ -142,20 +150,6 @@ export const Survey = () => {
}
/>

{/* <div className="mt-4">
<H2>Link zu Daten der Beteiligung </H2>
{survey.surveyResultsUrl ? (
<div className="mt-4 border rounded py-3.5">
<Link blank className="flex gap-1 pl-3.5" href={survey.surveyResultsUrl}>
Beteiligungs-Ergebnisse
<ArrowTopRightOnSquareIcon className="w-4 h-4" />
</Link>
</div>
) : (
<div className="mt-4">Es wurde bisher kein Link eingetragen.</div>
)}
</div> */}

<div className="mt-12">
<H2>Allgemeine Infos </H2>
<div className="mt-4 p-6 flex flex-col gap-y-2.5 bg-gray-100 rounded">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { TMapProps } from "src/survey-public/components/types"
import {
getFeedbackDefinitionBySurveySlug,
getResponseConfigBySurveySlug,
getSurveyDefinitionBySurveySlug,
} from "src/survey-public/utils/getConfigBySurveySlug"
import getSurveyResponseTopicsByProject from "src/survey-response-topics/queries/getSurveyResponseTopicsByProject"
import EditableSurveyResponseListItem from "src/survey-responses/components/feedback/EditableSurveyResponseListItem"
Expand Down Expand Up @@ -45,13 +46,13 @@ export const SurveyResponseWithLocation = () => {

const { evaluationRefs } = getResponseConfigBySurveySlug(survey.slug)
const feedbackDefinition = getFeedbackDefinitionBySurveySlug(survey.slug)
const surveyDefinition = getSurveyDefinitionBySurveySlug(survey.slug)

const locationRef = evaluationRefs["feedback-location"]

const mapProps = feedbackDefinition!.pages[0]!.questions.find((q) => q.id === locationRef)!
const mapProps = feedbackDefinition!.pages[1]!.questions.find((q) => q.id === locationRef)!
.props as TMapProps

const maptilerStyleUrl = mapProps.maptilerStyleUrl
const maptilerUrl = surveyDefinition.maptilerUrl
const defaultViewState = mapProps?.config?.bounds

if (!surveyResponsesFeedbackPartWithLocation?.length) return
Expand All @@ -73,7 +74,7 @@ export const SurveyResponseWithLocation = () => {
<div className="flex flex-col lg:flex-row gap-2">
<section className="lg:w-[46%] shrink-0">
<SurveyFeedbackWithLocationOverviewMap
maptilerStyleUrl={maptilerStyleUrl}
maptilerUrl={maptilerUrl}
defaultViewState={defaultViewState}
selectedSurveyResponse={selectedSurveyResponse}
surveyResponsesFeedbackPartWithLocation={surveyResponsesFeedbackPartWithLocation}
Expand Down
15 changes: 7 additions & 8 deletions src/pages/beteiligung/[surveySlug]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,27 @@ import { useQuery } from "@blitzjs/rpc"
import { Suspense } from "react"
import { Spinner } from "src/core/components/Spinner"

import { surveyDefinition as surveyDefinitionRS8 } from "src/survey-public/rs8/data/survey"
import { surveyDefinition as surveyDefinitionFRM7 } from "src/survey-public/frm7/data/survey"

import SurveyInactivePage from "src/survey-public/components/SurveyInactivePage"
import { SurveyRS8 } from "src/survey-public/rs8/SurveyRS8"
import getPublicSurveyBySlug from "src/surveys/queries/getPublicSurveyBySlug"
import { SurveyFRM7 } from "src/survey-public/frm7/SurveyFRM7"
import { SurveyBB } from "src/survey-public/radnetz-brandenburg/SurveyBB"
import getPublicSurveyBySlug from "src/surveys/queries/getPublicSurveyBySlug"

const PublicSurveyPageWithQuery = () => {
const surveySlug = useParam("surveySlug", "string")
const [survey] = useQuery(getPublicSurveyBySlug, { slug: surveySlug! })
// only returns something if there is a 'Survey' in the DB with the slug (url params) and the slug is either rs8 or frm7
if (!survey) return null
if (surveySlug === "rs8")
if (surveySlug === "frm7")
return survey.active ? (
<SurveyRS8 surveyId={survey.id} />
<SurveyFRM7 surveyId={survey.id} />
) : (
<SurveyInactivePage surveyDefinition={surveyDefinitionRS8} />
<SurveyInactivePage surveyDefinition={surveyDefinitionFRM7} />
)
if (surveySlug === "frm7")
if (surveySlug === "radnetz-brandenburg")
return survey.active ? (
<SurveyFRM7 surveyId={survey.id} />
<SurveyBB surveyId={survey.id} />
) : (
<SurveyInactivePage surveyDefinition={surveyDefinitionFRM7} />
)
Expand Down
40 changes: 10 additions & 30 deletions src/survey-public/components/Email.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { iframeResizer } from "iframe-resizer"
import { useEffect } from "react"
import { SurveyH2, SurveyP } from "./core/Text"
import { SurveyScreenHeader } from "./core/layout/SurveyScreenHeader"
import { SurveyLink } from "./core/links/SurveyLink"
import { TEmail } from "./types"
Expand All @@ -12,44 +11,25 @@ type Props = {
}

export const Email: React.FC<Props> = ({ email }) => {
const { description, questionText, button, title, mailjetWidgetUrl, homeUrl } = email
const { description, button, title, mailjetWidgetUrl, homeUrl } = email

useEffect(() => {
iframeResizer({}, "#mailjet-widget")
}, [])

return (
<section>
<SurveyScreenHeader title={title.de} />
<SurveyH2>{questionText.de}</SurveyH2>
<SurveyP>{description.de}</SurveyP>
<SurveyH2>Möchten Sie uns noch etwas mit auf den Weg geben?</SurveyH2>
<SurveyP>
Wenn Sie noch weiteres Feedback zur Online-Beteiligung haben, können Sie dies gerne an{" "}
<SurveyLink href="mailto:[email protected]?subject=Feedback zum FRM7">
[email protected]
</SurveyLink>{" "}
senden.{" "}
</SurveyP>
<SurveyP className="mt-6">
<i className="mt-6">
<strong>Transparenzhinweis</strong>: Die Befragung wurde um die Fragen („Sind Sie bzw.
Ihre Eltern in Deutschland geboren“) gekürzt, da diese bei Teilnehmenden zu Irritationen
geführt haben. Ziel der Fragen im Rahmen des Forschungsprojekts war die Ermittlung, welche
Zielgruppen in zukünftigen Beteiligungen ggf. noch gezielter angesprochen werden müssen.
Nach eingängiger Diskussion wurde entschieden, die beiden Fragen zu entfernen.
</i>
</SurveyP>

<div
className="rounded border border-gray-300 my-6 mt-10"
dangerouslySetInnerHTML={{
__html: `
<SurveyScreenHeader title={title.de} description={description.de} />
{mailjetWidgetUrl && (
<div
className="rounded border border-gray-300 my-6 mt-10"
dangerouslySetInnerHTML={{
__html: `
<iframe id="mailjet-widget" data-w-type="embedded" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="${mailjetWidgetUrl}" width="100%" style="height: 0px;"></iframe>
`,
}}
/>

}}
/>
)}
<div className="pt-10">
<SurveyLink button={button.color} href={homeUrl}>
{button.label.de}
Expand Down
1 change: 0 additions & 1 deletion src/survey-public/components/More.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { SurveyH2 } from "./core/Text"
import { SurveyButton } from "./core/buttons/SurveyButton"
import { SurveyButtonWrapper } from "./core/buttons/SurveyButtonWrapper"
import { SurveyScreenHeader } from "./core/layout/SurveyScreenHeader"
Expand Down
4 changes: 4 additions & 0 deletions src/survey-public/components/Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { SurveyButtonWithAction } from "./core/buttons/SurveyButtonWithAction"
import { SurveyButtonWrapper } from "./core/buttons/SurveyButtonWrapper"
import type { TPage as TPage } from "src/survey-public/components/types"
import { Question } from "./Question"
import { SurveyP } from "./core/Text"
export { FORM_ERROR } from "src/core/components/forms"

type Props = {
Expand Down Expand Up @@ -39,6 +40,9 @@ export const Page: React.FC<Props> = ({ page, buttonActions, completed }) => {
)
})}
</SurveyButtonWrapper>
<SurveyP className="mt-6">
* Pflichtfelder Um Fortzufahren bitte alle Pflichtfelder ausfüllen.
</SurveyP>
</section>
)
}
36 changes: 31 additions & 5 deletions src/survey-public/components/Question.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { TQuestion, TSingleOrMultiResponseProps } from "src/survey-public/components/types"
import {
TQuestion,
TSingleOrMultiResponseProps,
TTextProps,
} from "src/survey-public/components/types"
import { SurveyH2 } from "./core/Text"
import { SurveyLabeledCheckboxGroup } from "./core/form/SurveyLabeledCheckboxGroup"
import { SurveyLabeledRadiobuttonGroup } from "./core/form/SurveyLabeledRadiobuttonGroup"
import { SurveyLabeledTextareaField } from "./core/form/SurveyLabeledTextareaField"
import { SurveyLabeledTextField } from "./core/form/SurveyLabeledTextField"
import { SurveyLabeledReadOnlyTextField } from "./core/form/SurveyLabeledReadOnlyTextField"
import { read } from "fs"
export { FORM_ERROR } from "src/core/components/forms"

type TSingleOrMultuResponseComponentProps = {
Expand Down Expand Up @@ -40,13 +47,30 @@ const MultipleResponseComponent: React.FC<TSingleOrMultuResponseComponentProps>

type TTextResponseComponentProps = {
id: number
}
} & TTextProps
type TReadOnlyResponseComponentProps = {
id: number
queryId: string
} & TTextProps

const TextResponseComponent: React.FC<TTextResponseComponentProps> = ({ id, placeholder }) => (
<>
<SurveyLabeledTextareaField name={`text-${id}`} label={""} placeholder={placeholder?.de} />
</>
)

const TextResponseComponent: React.FC<TTextResponseComponentProps> = ({ id }) => (
const TextFieldResponseComponent: React.FC<TTextResponseComponentProps> = ({ id, placeholder }) => (
<>
<SurveyLabeledTextareaField name={`text-${id}`} label={""} />
<SurveyLabeledTextField name={`text-${id}`} placeholder={placeholder?.de} label={""} />
</>
)

const ReadOnlyResponseComponent: React.FC<TReadOnlyResponseComponentProps> = ({ id, queryId }) => (
<>
<SurveyLabeledReadOnlyTextField readOnly name={`text-${id}`} label={""} queryId={queryId} />
</>
)

// TODO type
const CustomComponent = (props: any) => (
<div className="border-2 border-black bg-gray-200 p-1">
Expand All @@ -60,6 +84,8 @@ const components = {
singleResponse: SingleResponseComponent,
multipleResponse: MultipleResponseComponent,
text: TextResponseComponent,
textfield: TextFieldResponseComponent,
readOnly: ReadOnlyResponseComponent,
custom: CustomComponent,
}

Expand All @@ -70,7 +96,7 @@ export const Question: React.FC<Props> = ({ question, className }) => {
const Component = components[component] || null
return (
<div className={className} key={id}>
<SurveyH2>{label.de}</SurveyH2>
<SurveyH2>{label.de} *</SurveyH2>
{help && <div className="-mt-4 mb-6 text-gray-400 text-sm">{help.de}</div>}
{/* @ts-ignore */}
{Component && <Component id={id} {...props} />}
Expand Down
15 changes: 15 additions & 0 deletions src/survey-public/components/Start.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { SurveyButton } from "./core/buttons/SurveyButton"
import { SurveyButtonWrapper } from "./core/buttons/SurveyButtonWrapper"

type Props = { onStartClick: () => void; startContent: React.ReactNode }

export const Start: React.FC<Props> = ({ onStartClick, startContent }) => {
return (
<div>
{startContent}
<SurveyButtonWrapper>
<SurveyButton onClick={onStartClick}>Beteiligung starten</SurveyButton>
</SurveyButtonWrapper>
</div>
)
}
2 changes: 1 addition & 1 deletion src/survey-public/components/Survey.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export const Survey: React.FC<Props> = ({ survey, onSubmit }) => {
}
// @ts-ignore no worries - this works
const response = values[id]
if (["singleResponse", "text"].includes(component)) {
if (["singleResponse", "text", "textfield"].includes(component)) {
return response !== null
} else {
return !!response.length
Expand Down
Loading

0 comments on commit 619919f

Please sign in to comment.