Skip to content

geeksblabla/stateofdev.ma

Repository files navigation

All Contributors

logo

State Of Dev in Morocco Website


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

πŸš€ Quick start

  1. Fork and clone the project
git clone [email protected]:your-username/stateofdev.ma.git
  1. 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
  1. Open the source code and start editing!

Your website is now running at http://localhost:4321

How the survey works

The survey form submission process is designed to be secure, anonymous, and user-friendly. Here's an overview of how it works:

  1. 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.
  2. 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.
  3. 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.
  4. 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.

How the results works

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.

🧐 Want to contribute ?

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.

Licensing

The code in this project is licensed under MIT license.

The Data in ./results is licensed under ODC-ODbL License.

Contributors ✨

Thanks goes to these wonderful people (emoji key):

Youssouf EL AZIZI
Youssouf EL AZIZI

πŸ’» πŸ“– πŸ–‹ πŸ€”
Mohammed Aboullaite
Mohammed Aboullaite

πŸ’» πŸ–‹ πŸ€”
Ismail El Azizi
Ismail El Azizi

🎨 πŸ–‹ πŸ€”
djalal
djalal

πŸ–‹ πŸ€”
Meriem Zaid
Meriem Zaid

πŸ–‹ πŸ€”
Mohamed Ez-zarghili
Mohamed Ez-zarghili

πŸ–‹ πŸ€”
Aymane Boumaaza
Aymane Boumaaza

πŸ–‹
Haytam Zanid
Haytam Zanid

πŸ–‹
Abdelfettah SGHIOUAR
Abdelfettah SGHIOUAR

πŸ–‹
Youness IABITEN
Youness IABITEN

πŸ–‹
Ismail Tlemçani
Ismail Tlemçani

πŸ–‹
Abderrahim SOUBAI
Abderrahim SOUBAI

πŸ–‹
Mustapha
Mustapha

πŸ–‹
el amraoui Sohayb
el amraoui Sohayb

πŸ–‹
Yasser Tahiri
Yasser Tahiri

πŸ–‹
Mohammed Daoudi
Mohammed Daoudi

πŸ–‹
Bilal
Bilal

πŸ–‹ πŸ’»

This project follows the all-contributors specification. Contributions of any kind welcome!

Credit

This project is inspired by :