StateOfDev.ma is a survey centered around software developers in Morocco by GeeksBlaBla Morocco Community.
We wanted to know how we can help and support each other, and overall be able to better respond to developers evolving needs.
The website is built using AstroJs
- Fork and clone the project
git clone [email protected]:your-username/stateofdev.ma.git
- Configure Project and Start developing.
-
Go to Firebase Console and Create a firebase application, activate anonymous authentication and enable Firestore database on production mode to set data to private by default as we are going to user firebase admin sdk to write data to firestore database.
-
Go to Project settings > service accounts > generate new private key and add missed vars to your .env file.
-
Go to Cloudflare Turnstile and create a new site and get your keys.(optional)
-
Copy your keys to
.env.local
:
# Client-side Firebase configuration
PUBLIC_FIREBASE_API_KEY=
PUBLIC_FIREBASE_AUTH_DOMAIN=
PUBLIC_FIREBASE_STORAGE_BUCKET=
PUBLIC_FIREBASE_MESSAGING_SENDER_ID=
PUBLIC_FIREBASE_APP_ID=
# Server-side Firebase configuration
FIREBASE_PRIVATE_KEY_ID=
FIREBASE_PRIVATE_KEY=
FIREBASE_PROJECT_ID=
FIREBASE_CLIENT_EMAIL=
FIREBASE_CLIENT_ID=
FIREBASE_AUTH_URI=
FIREBASE_TOKEN_URI=
FIREBASE_AUTH_CERT_URL=
FIREBASE_CLIENT_CERT_URL=
# captcha keys (optional) make sure to set it to false in dev mode
CAPTCHA_ENABLED=false
CAPTCHA_SITE_KEY=
CAPTCHA_SECRET_KEY=
- Navigate into your new website's directory and start it up.
cd stateofdev.ma/
pnpm install
pnpm dev
- Open the source code and start editing!
Your website is now running at http://localhost:4321
The survey form submission process is designed to be secure, anonymous, and user-friendly. Here's an overview of how it works:
-
Session Initialization (Before Start Page)
- When the user clicks the
Take part in the survey
button from the home page, they are redirected to the/before-start
page where they find important information about the survey. - A CAPTCHA is displayed to prevent spam submissions(using Cloudflare Turnstile).
- When the user clicks "Start":
- An anonymous Firebase authentication session is created.
- The session token and CAPTCHA token are sent to the server (actions/initialize-session.ts).
- The server (actions/initialize-session.ts) validates the Firebase session and the CAPTCHA, initializes the session, and sets a session cookie.
- Upon successful initialization, the user is redirected to the
/survey
page.
- When the user clicks the
-
Survey Page
- The page checks for an active session before displaying the survey form.
- If no valid session is found, the user is redirected back to the
/before-start
page. - With a valid session, the SurveyForm component is rendered.
-
Survey Form Component
- Questions are loaded from YAML files and presented to the user in sections.
- Based on the question type, the form changes (radio, checkbox, etc.) and shows a text area if the user selects an option that contains "other".
- At the end of each section, answers are validated and sent to the server (actions/submit-answers.ts).
// example of the data sent to the server const answers = { "profile-q-0": 1, "profile-q-1": 2, "profile-q-2": [3, 2], // multiple choice question "profile-q-3": 6, // single choice question "profile-q-3-other": "text", // other text "profile-q-4": null // null if the question is not answered (skip button) };
For every question, we send the index of choices selected by the user. It should be a number if the question is single choice, and an array of numbers if the question is multiple choice. We also send "other" text if the user selects an option that contains "other" and adds custom text to the text area.
- The server (actions/submit-answers.ts) verifies the session, processes the answers, and saves them to the Firestore database with the user ID as the document ID. This way, we can avoid duplicate submissions, and in case of a repeat submission, we will only update the existing document.
-
Completion and Thanks Page
- After completing all sections, the user is redirected to the "Thanks" page.
- A thank you message is displayed along with social sharing options.
Every day at 12:00 AM UTC we run a github action that export data from firestore and the file should look like this:
{
"results": [
{
"profile-q-0": 1,
"profile-q-1": 2,
"profile-q-2": [3, 2],
"profile-q-3": 6,
"profile-q-3-other": "text",
"lastSignInTime": "Tue, 17 Sep 2024 11:57:46 GMT",
"creationTime": "Tue, 17 Sep 2024 11:57:46 GMT",
"userId": "..."
},
...
]
}
Then we generate a json file for survey questions with their choices and ids.
{
"profile-q-0": {
"label": "What is your gender?",
"required": true,
"multiple": false,
"choices": ["Male", "Female"]
},
"profile-q-1": {
"label": "What is your age?",
"required": true,
"choices": [
"Younger than 18 years",
"18 to 24 years",
"25 to 34 years",
"35 to 44 years",
"45 or older"
],
"multiple": false
},
...
}
Now that we have the results and the questions. we use getQuestion
in components/chart/utils.ts
file to get data for any question id then render it using Chart
component.
If you want to contribute check out the help wanted issues for things that need fixing, or suggest some new features by opening new issues.
The code in this project is licensed under MIT license.
The Data in ./results
is licensed under ODC-ODbL License.
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!
This project is inspired by :