Skip to content

Feat 99 setup wizard#173

Open
mohammadsherif0 wants to merge 51 commits intodevfrom
feat-99-setup-wizard
Open

Feat 99 setup wizard#173
mohammadsherif0 wants to merge 51 commits intodevfrom
feat-99-setup-wizard

Conversation

@mohammadsherif0
Copy link
Copy Markdown
Collaborator

@mohammadsherif0 mohammadsherif0 commented Apr 20, 2026

Main Description

This branch delivers a guided onboarding experience for CARE by introducing a first-time setup wizard and aligning the admin Settings UI to the same structure and language.
It addresses the original problem that setup was fragmented, technical, and hard to follow by having a clear step flow (admin creation, general, mail, registration, moodle, summary).

#99

New User Features

  • First-time setup wizard flow with ordered steps for admin account creation and system configuration.
  • Summary step before finish so admins can review all selected values in one place.
  • Import settings from previous instance inside the wizard via JSON.
  • Download current settings snapshot as JSON to reuse across deployments.
  • Built-in test mail action during setup so admins can verify mail settings before finishing setup.
  • Mail setting updates apply directly from Dashboard Save Settings (no backend restart required).
  • Clearer setting labels/grouping for better readability compared to technical/raw key names.

New Dev Features

  • Local dev workflow target split (make dev vs make dev-wizard) to simplify testing both default paths.
  • Setup mail test capability wired into the setup flow, making mail configuration easier to validate during development and QA.
  • Mail service settings now refresh without manual backend restart, reducing friction during iterative config/testing.

Improvements

  • Simpler first-time user experience by replacing scattered dashboard configuration with one guided setup path.
  • Faster initial setup completion through step-by-step flow and in-wizard review.
  • Settings page rework toward wizard-like structure, improving consistency between first-time setup and ongoing configuration.
  • Better subsection ordering and grouping in settings/wizard views.
  • Operational UX improvement for mail configuration: changing mail settings and saving in dashboard is enough; no backend refresh workflow needed.

@mohammadsherif0 mohammadsherif0 self-assigned this Apr 20, 2026
@mohammadsherif0 mohammadsherif0 marked this pull request as ready for review April 20, 2026 15:27
Copy link
Copy Markdown
Collaborator

@dennis-zyska dennis-zyska left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice implementation, I added a few comments, let me know if anything is unclear

type: Sequelize.BOOLEAN,
defaultValue: false,
});
await queryInterface.addColumn('setting', 'wizardStep', {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't that be a FK to the id of the wizard_step table?

type: Sequelize.STRING,
allowNull: true,
},
type: {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use integer instead of strings in that table? I guess the types are predefined somehow?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quick verification question: are they still visible for everyone after that?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move those settings just to our settings table instead of creating a new table just for those two entries?


module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.addColumn('setting', 'displayName', {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move those column changes to backend/db/migrations/20260119185850-extend-setting-wizard.js, that would be more readable, the entries can be still in here but we should change the name of the migration into -basic-setting-displayName

* First-time setup wizard: Admin, General (optional Moodle + JSON import), Mail, Registration, Summary.
* Fetches /setup/config for steps and wizardSettings. On Finish, calls settingSave and redirects.
*
* @author CARE
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CARE is not the author

registration: ["Enable registration", "Information requested at registration", "Consent options", "Email verification rate limit"],
};

function wizardValueToFormString(v) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we usually not defining variables outside of the export default, we therefore have the assets, if the function are used many times in the software, otherwise it should be under methods

return;
}

if (!this.$socket.connected) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we should additional add here the socket connection, maybe we can handle that in the /setup/state route as well and use our default mechanism for the socket connection. Then we don't need it here, also reducing this huge code here a bit

Comment thread frontend/src/router.js
router.beforeEach(async (to, from, next) => {
if (to.path === "/wizard") {
try {
const r = await fetch(getServerURL() + "/auth/check", { credentials: "include" });
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have the feeling this is not a good idea, first we have two beforeEach checks here, why not integrating it in the other, second, why not checking it inside of the component?

Comment thread frontend/src/router.js
}
if (!to.meta.requireAuth && !to.meta.checkLogin) return next();
try {
const r = await fetch(getServerURL() + "/auth/check", { credentials: "include" });
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

especilly this seems like a lot of requests for each route change

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants