admin onboarding (#4863)

# Description of Changes

<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.

---------

Co-authored-by: EthanHealy01 <[email protected]>
This commit is contained in:
Anthony Stirling
2025-11-10 13:47:43 +00:00
committed by GitHub
co-authored by EthanHealy01
parent ebf4bab80b
commit 3cf89b6ede
8 changed files with 431 additions and 19 deletions
@@ -154,6 +154,7 @@ const AppConfigModal: React.FC<AppConfigModalProps> = ({ opened, onClose }) => {
opacity: isDisabled ? 0.5 : 1,
cursor: isDisabled ? 'not-allowed' : 'pointer',
}}
data-tour={`admin-${item.key}-nav`}
>
<LocalIcon icon={item.icon} width={iconSize} height={iconSize} style={{ color }} />
{!isMobile && (
@@ -185,7 +186,7 @@ const AppConfigModal: React.FC<AppConfigModalProps> = ({ opened, onClose }) => {
</div>
{/* Right content */}
<div className="modal-content">
<div className="modal-content" data-tour="settings-content-area">
<div className="modal-content-scroll">
{/* Sticky header with section title and small close button */}
<div
@@ -1,5 +1,5 @@
import React, { useState, useRef, forwardRef, useEffect } from "react";
import { ActionIcon, Stack, Divider } from "@mantine/core";
import { ActionIcon, Stack, Divider, Menu } from "@mantine/core";
import { useTranslation } from 'react-i18next';
import { useNavigate, useLocation } from 'react-router-dom';
import LocalIcon from '@app/components/shared/LocalIcon';
@@ -21,6 +21,7 @@ import {
getNavButtonStyle,
getActiveNavButton,
} from '@app/components/shared/quickAccessBar/QuickAccessBar';
import { Z_INDEX_OVER_FULLSCREEN_SURFACE } from '@app/styles/zIndex';
const QuickAccessBar = forwardRef<HTMLDivElement>((_, ref) => {
const { t } = useTranslation();
@@ -179,7 +180,7 @@ const QuickAccessBar = forwardRef<HTMLDivElement>((_, ref) => {
size: 'lg',
type: 'action',
onClick: () => {
startTour();
// This will be overridden by the wrapper logic
},
},
{
@@ -258,11 +259,70 @@ const QuickAccessBar = forwardRef<HTMLDivElement>((_, ref) => {
{/* Bottom section */}
<Stack gap="lg" align="center">
{bottomButtons.map((config, index) => (
<React.Fragment key={config.id}>
{renderNavButton(config, index)}
</React.Fragment>
))}
{bottomButtons.map((buttonConfig, index) => {
// Handle help button with menu or direct action
if (buttonConfig.id === 'help') {
const isAdmin = config?.isAdmin === true;
// If not admin, just show button that starts tools tour directly
if (!isAdmin) {
return (
<div
key={buttonConfig.id}
data-tour="help-button"
onClick={() => startTour('tools')}
>
{renderNavButton(buttonConfig, index)}
</div>
);
}
// If admin, show menu with both options
return (
<div key={buttonConfig.id} data-tour="help-button">
<Menu position="right" offset={10} zIndex={Z_INDEX_OVER_FULLSCREEN_SURFACE}>
<Menu.Target>
<div>{renderNavButton(buttonConfig, index)}</div>
</Menu.Target>
<Menu.Dropdown>
<Menu.Item
leftSection={<LocalIcon icon="view-carousel-rounded" width="1.25rem" height="1.25rem" />}
onClick={() => startTour('tools')}
>
<div>
<div style={{ fontWeight: 500 }}>
{t("quickAccess.helpMenu.toolsTour", "Tools Tour")}
</div>
<div style={{ fontSize: '0.875rem', opacity: 0.7 }}>
{t("quickAccess.helpMenu.toolsTourDesc", "Learn what the tools can do")}
</div>
</div>
</Menu.Item>
<Menu.Item
leftSection={<LocalIcon icon="admin-panel-settings-rounded" width="1.25rem" height="1.25rem" />}
onClick={() => startTour('admin')}
>
<div>
<div style={{ fontWeight: 500 }}>
{t("quickAccess.helpMenu.adminTour", "Admin Tour")}
</div>
<div style={{ fontSize: '0.875rem', opacity: 0.7 }}>
{t("quickAccess.helpMenu.adminTourDesc", "Explore admin settings & features")}
</div>
</div>
</Menu.Item>
</Menu.Dropdown>
</Menu>
</div>
);
}
return (
<React.Fragment key={buttonConfig.id}>
{renderNavButton(buttonConfig, index)}
</React.Fragment>
);
})}
</Stack>
</div>
</div>