includes/modals/wizard_modal.php

<!--
    Install wizard modal.

    First-run form: admin account + at least one tracked site. Submitted
    as JSON to /api/settings.php?action=install by wizard.js, which also
    manages adding/removing the repeatable site fieldsets below.
-->
<dialog class="modal" id="wizard-modal" open>
    <div>
        <h2><?= h(t('wizard.title')) ?></h2>
        <p><?= h(t('wizard.description')) ?></p>

        <form action="api/settings.php?action=install" id="wizard-form" method="post">
            <section>
                <h3><?= h(t('settings.dashboard.title')) ?></h3>
                <p><?= h(t('settings.instance.help')) ?></p>

                <label>
                    <?= h(t('settings.instance.name')) ?>
                    <small><?= h(t('settings.instance.name.help')) ?></small>
                    <input name="dashboard.instance_name" required type="text" value="Brivacia">
                </label>
            </section>

            <section>
                <h3><?= h(t('settings.admin.title')) ?></h3>
                <p><?= h(t('settings.admin.help')) ?></p>

                <label>
                    <?= h(t('settings.admin.username')) ?>
                    <small><?= h(t('settings.admin.username.help')) ?></small>
                    <input autocapitalize="off" autocomplete="username" autocorrect="off" maxlength="32" minlength="3" name="admin.username" pattern="[A-Za-z0-9._-]+" required spellcheck="false" type="text">
                </label>

                <label>
                    <?= h(t('settings.admin.password')) ?>
                    <small><?= h(t('settings.admin.password.help')) ?></small>
                    <input autocapitalize="off" autocomplete="new-password" autocorrect="off" maxlength="128" minlength="12" name="admin.password" required spellcheck="false" type="password">
                </label>

                <label>
                    <?= h(t('settings.admin.password.confirm')) ?>
                    <small><?= h(t('settings.admin.password.confirm.help')) ?></small>
                    <input autocapitalize="off" autocomplete="new-password" autocorrect="off" maxlength="128" minlength="12" name="admin.password_confirm" required spellcheck="false" type="password">
                </label>
            </section>

            <section id="wizard-sites">
                <h3><?= h(t('settings.tracked_sites.title')) ?></h3>
                <p><?= h(t('settings.tracked_sites.help')) ?></p>

                <div>
                    <fieldset>
                        <label>
                            <?= h(t('settings.tracked_sites.code')) ?>
                            <small><?= h(t('settings.tracked_sites.code.help')) ?></small>
                            <input name="sites[0][code]" placeholder="main" required type="text" value="">
                        </label>

                        <label>
                            <?= h(t('settings.tracked_sites.domain')) ?>
                            <small><?= h(t('settings.tracked_sites.domain.help')) ?></small>
                            <input name="sites[0][domain]" placeholder="<?= h(t('settings.tracked_sites.domain.placeholder')) ?>" required type="text" value="">
                        </label>

                        <button type="button" value="remove-site">
                            <?= icon('trash') ?> <?= h(t('settings.tracked_sites.remove')) ?>
                        </button>
                    </fieldset>
                </div>

                <button type="button" value="add-site">
                    <?= h(t('settings.tracked_sites.add')) ?>
                </button>

                <template id="wizard-site-template">
                    <fieldset>
                        <label>
                            <?= h(t('settings.tracked_sites.code')) ?>
                            <small><?= h(t('settings.tracked_sites.code.help')) ?></small>
                            <input name="sites[__INDEX__][code]" placeholder="main" required type="text" value="">
                        </label>

                        <label>
                            <?= h(t('settings.tracked_sites.domain')) ?>
                            <small><?= h(t('settings.tracked_sites.domain.help')) ?></small>
                            <input name="sites[__INDEX__][domain]" placeholder="<?= h(t('settings.tracked_sites.domain.placeholder')) ?>" required type="text" value="">
                        </label>

                        <button type="button" value="remove-site">
                            <?= icon('trash') ?> <?= h(t('settings.tracked_sites.remove')) ?>
                        </button>
                    </fieldset>
                </template>
            </section>

            <section>
                <h3><?= h(t('settings.privacy.title')) ?></h3>
                <p><?= h(t('settings.privacy.help')) ?></p>

                <label>
                    <?= h(t('settings.privacy.country_provider')) ?>
                    <small><?= h(t('settings.privacy.country_provider.help')) ?></small>
                    <span>
                        <select name="privacy.country_provider">
                            <option value="none"><?= h(t('settings.privacy.country_provider.none')) ?></option>
                            <option value="blurloc"><?= h(t('settings.privacy.country_provider.blurloc')) ?></option>
                            <option value="cloudflare"><?= h(t('settings.privacy.country_provider.cloudflare')) ?></option>
                        </select>
                    </span>
                </label>

                <label>
                    <?= h(t('settings.privacy.ip_prefix_octets')) ?>
                    <small><?= h(t('settings.privacy.ip_prefix_octets.help')) ?></small>
                    <span>
                        <select name="privacy.ip_prefix_octets">
                            <option value="2"><?= h(t('settings.privacy.ip_prefix_octets.2')) ?></option>
                            <option value="3"><?= h(t('settings.privacy.ip_prefix_octets.3')) ?></option>
                        </select>
                    </span>
                </label>
            </section>

            <section>
                <h3><?= h(t('settings.referrers.title')) ?></h3>
                <p><?= h(t('settings.referrers.help')) ?></p>

                <label>
                    <input name="referrers.auto_referrers" type="checkbox" checked>
                    <?= h(t('settings.referrers.auto_referrers')) ?>
                    <small><?= h(t('settings.referrers.auto_referrers.help')) ?></small>
                </label>

                <label>
                    <input name="referrers.auto_referrer_icons" type="checkbox" checked>
                    <?= h(t('settings.referrers.auto_referrer_icons')) ?>
                    <small><?= h(t('settings.referrers.auto_referrer_icons.help')) ?></small>
                </label>
            </section>

            <p>
                <?= h(t('wizard.help')) ?>
                <?= externalLink('https://code.breat.fr/b/brivacia/docs/faq', h(t('wizard.help.link'))) ?><?= currentLang() !== 'en' ? ' ' . h(t('ui.en')) : '' ?></span>.
            </p>

            <div>
                <p
                    id="wizard-message"
                    role="status"
                    data-installing="<?= h(t('wizard.messages.installing')) ?>"
                    data-installed="<?= h(t('wizard.messages.installed')) ?>"
                    data-error="<?= h(t('wizard.messages.error')) ?>"
                    data-network-error="<?= h(t('settings.messages.network_error')) ?>"
                ></p>

                <button type="submit">
                    <?= icon('save') ?> <?= h(t('wizard.install')) ?>
                </button>
            </div>
        </form>
    </div>
</dialog>

Contribute