mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-08-27 06:39:24 +00:00
V2 styling requests (#4288)
some of the requested changes warrant discussion so I haven't applied all of them here. Making a draft PR for now, we can discuss the rest later # Description of Changes See Matts todo list, the crossed out items are what were addressed in this PR --- ## 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) ### 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: James Brunton <jbrunton96@gmail.com>
This commit is contained in:
parent
9360a36c31
commit
3d26b054f1
@ -1,4 +1,4 @@
|
||||
<svg width="146" height="157" viewBox="0 0 146 157" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3.77397 72.5462L93.6741 23.0462L94.7739 70.0462L3.77395 119.046L3.77397 72.5462Z" fill="#E6E6E6" fill-opacity="0.4"/>
|
||||
<path d="M50.774 73.5735L96.387 50.2673L142 26.961L142 71.687L50.7739 122.046L50.774 73.5735Z" fill="#E6E6E6" fill-opacity="0.7"/>
|
||||
<svg width="92" height="100" viewBox="0 0 92 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 50L60 0V46.5L0 96.5V50Z" fill="#E6E6E6" fill-opacity="0.4"/>
|
||||
<path d="M32 53L92 3V49.5L32 99.5V53Z" fill="#E6E6E6" fill-opacity="0.7"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 366 B After Width: | Height: | Size: 253 B |
@ -1,4 +1,4 @@
|
||||
<svg width="146" height="146" viewBox="0 0 146 146" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3.77397 72.5462L93.6741 23.0462L94.7739 70.0462L3.77395 119.046L3.77397 72.5462Z" fill="#ACACAC" fill-opacity="0.3"/>
|
||||
<path d="M50.774 73.5735L96.387 50.2673L142 26.961L142 71.687L50.7739 122.046L50.774 73.5735Z" fill="#FC9999" fill-opacity="0.5"/>
|
||||
<svg width="92" height="100" viewBox="0 0 92 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 50L60 0V46.5L0 96.5V50Z" fill="#ACACAC" fill-opacity="0.3"/>
|
||||
<path d="M32 53L92 3V49.5L32 99.5V53Z" fill="#FC9999" fill-opacity="0.5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 366 B After Width: | Height: | Size: 253 B |
@ -26,7 +26,7 @@ const AllToolsNavButton: React.FC<AllToolsNavButtonProps> = ({ activeButton, set
|
||||
|
||||
const iconNode = (
|
||||
<span className="iconContainer">
|
||||
<AppsIcon sx={{ fontSize: '1.5rem' }} />
|
||||
<AppsIcon sx={{ fontSize: '2rem' }} />
|
||||
</span>
|
||||
);
|
||||
|
||||
|
@ -36,7 +36,7 @@ const LandingPage = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Container size="lg" p={0} h="100%" className="flex items-center justify-center" style={{ position: 'relative' }}>
|
||||
<Container size="70rem" p={0} h="102%" className="flex items-center justify-center" style={{ position: 'relative' }}>
|
||||
{/* White PDF Page Background */}
|
||||
<Dropzone
|
||||
onDrop={handleFileDrop}
|
||||
@ -48,7 +48,7 @@ const LandingPage = () => {
|
||||
left: '50%',
|
||||
transform: 'translateX(-50%)',
|
||||
bottom: 0,
|
||||
borderRadius: '0.5rem 0.5rem 0 0',
|
||||
borderRadius: '0.25rem 0.25rem 0 0',
|
||||
filter: 'var(--drop-shadow-filter)',
|
||||
backgroundColor: 'var(--landing-paper-bg)',
|
||||
transition: 'background-color 0.4s ease',
|
||||
@ -66,7 +66,7 @@ const LandingPage = () => {
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
right: ".5rem",
|
||||
right: 0,
|
||||
zIndex: 10,
|
||||
|
||||
}}
|
||||
@ -75,15 +75,13 @@ const LandingPage = () => {
|
||||
src={colorScheme === 'dark' ? '/branding/StirlingPDFLogoNoTextDark.svg' : '/branding/StirlingPDFLogoNoTextLight.svg'}
|
||||
alt="Stirling PDF Logo"
|
||||
style={{
|
||||
width: '10rem',
|
||||
height: 'auto',
|
||||
pointerEvents: 'none',
|
||||
marginTop: '-0.5rem'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={`min-h-[25vh] flex flex-col items-center justify-center px-8 py-8 w-full min-w-[360px] border transition-all duration-200 dropzone-inner relative`}
|
||||
className={`min-h-[45vh] flex flex-col items-center justify-center px-8 py-8 w-full min-w-[30rem] max-w-[calc(100%-2rem)] border transition-all duration-200 dropzone-inner relative`}
|
||||
style={{
|
||||
borderRadius: '0.5rem',
|
||||
backgroundColor: 'var(--landing-inner-paper-bg)',
|
||||
|
@ -68,7 +68,7 @@ const QuickAccessBar = forwardRef<HTMLDivElement>(({
|
||||
{
|
||||
id: 'automate',
|
||||
name: t("quickAccess.automate", "Automate"),
|
||||
icon: <LocalIcon icon="automation-outline" width="1.25rem" height="1.25rem" />,
|
||||
icon: <LocalIcon icon="automation-outline" width="1.6rem" height="1.6rem" />,
|
||||
size: 'lg',
|
||||
isRound: false,
|
||||
type: 'navigation',
|
||||
@ -80,7 +80,7 @@ const QuickAccessBar = forwardRef<HTMLDivElement>(({
|
||||
{
|
||||
id: 'files',
|
||||
name: t("quickAccess.files", "Files"),
|
||||
icon: <LocalIcon icon="folder-rounded" width="1.25rem" height="1.25rem" />,
|
||||
icon: <LocalIcon icon="folder-rounded" width="1.6rem" height="1.6rem" />,
|
||||
isRound: true,
|
||||
size: 'lg',
|
||||
type: 'modal',
|
||||
@ -151,7 +151,7 @@ const QuickAccessBar = forwardRef<HTMLDivElement>(({
|
||||
|
||||
<div className="flex flex-col items-center gap-1" style={{ marginTop: index === 0 ? '0.5rem' : "0rem" }}>
|
||||
<ActionIcon
|
||||
size={isNavButtonActive(config, activeButton, isFilesModalOpen, configModalOpen, selectedToolKey, leftPanelView) ? (config.size || 'xl') : 'lg'}
|
||||
size={isNavButtonActive(config, activeButton, isFilesModalOpen, configModalOpen, selectedToolKey, leftPanelView) ? (config.size || 'lg') : 'lg'}
|
||||
variant="subtle"
|
||||
onClick={() => {
|
||||
config.onClick();
|
||||
|
@ -6,6 +6,7 @@ import VisibilityIcon from "@mui/icons-material/Visibility";
|
||||
import EditNoteIcon from "@mui/icons-material/EditNote";
|
||||
import FolderIcon from "@mui/icons-material/Folder";
|
||||
import { ModeType, isValidMode } from '../../contexts/NavigationContext';
|
||||
import { Tooltip } from "./Tooltip";
|
||||
|
||||
const viewOptionStyle = {
|
||||
display: 'inline-flex',
|
||||
@ -17,8 +18,8 @@ const viewOptionStyle = {
|
||||
}
|
||||
|
||||
|
||||
// Create view options with icons and loading states
|
||||
const createViewOptions = (switchingTo: ModeType | null) => [
|
||||
// Build view options showing text only for current view; others icon-only with tooltip
|
||||
const createViewOptions = (currentView: ModeType, switchingTo: ModeType | null) => [
|
||||
{
|
||||
label: (
|
||||
<div style={viewOptionStyle as React.CSSProperties}>
|
||||
@ -34,27 +35,35 @@ const createViewOptions = (switchingTo: ModeType | null) => [
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<div style={viewOptionStyle as React.CSSProperties}>
|
||||
{switchingTo === "pageEditor" ? (
|
||||
<Loader size="xs" />
|
||||
) : (
|
||||
<EditNoteIcon fontSize="small" />
|
||||
)}
|
||||
<span>Page Editor</span>
|
||||
</div>
|
||||
<Tooltip content="Page Editor" position="bottom" arrow={true}>
|
||||
<div style={viewOptionStyle as React.CSSProperties}>
|
||||
{currentView === "pageEditor" ? (
|
||||
<>
|
||||
{switchingTo === "pageEditor" ? <Loader size="xs" /> : <EditNoteIcon fontSize="small" />}
|
||||
<span>Page Editor</span>
|
||||
</>
|
||||
) : (
|
||||
switchingTo === "pageEditor" ? <Loader size="xs" /> : <EditNoteIcon fontSize="small" />
|
||||
)}
|
||||
</div>
|
||||
</Tooltip>
|
||||
),
|
||||
value: "pageEditor",
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<div style={viewOptionStyle as React.CSSProperties}>
|
||||
{switchingTo === "fileEditor" ? (
|
||||
<Loader size="xs" />
|
||||
) : (
|
||||
<FolderIcon fontSize="small" />
|
||||
)}
|
||||
<span>File Manager</span>
|
||||
</div>
|
||||
<Tooltip content="Active Files" position="bottom" arrow={true}>
|
||||
<div style={viewOptionStyle as React.CSSProperties}>
|
||||
{currentView === "fileEditor" ? (
|
||||
<>
|
||||
{switchingTo === "fileEditor" ? <Loader size="xs" /> : <FolderIcon fontSize="small" />}
|
||||
<span>Active Files</span>
|
||||
</>
|
||||
) : (
|
||||
switchingTo === "fileEditor" ? <Loader size="xs" /> : <FolderIcon fontSize="small" />
|
||||
)}
|
||||
</div>
|
||||
</Tooltip>
|
||||
),
|
||||
value: "fileEditor",
|
||||
},
|
||||
@ -103,11 +112,10 @@ const TopControls = ({
|
||||
{!isToolSelected && (
|
||||
<div className="flex justify-center mt-[0.5rem]">
|
||||
<SegmentedControl
|
||||
data={createViewOptions(switchingTo)}
|
||||
data={createViewOptions(currentView, switchingTo)}
|
||||
value={currentView}
|
||||
onChange={handleViewChange}
|
||||
color="blue"
|
||||
radius="xl"
|
||||
fullWidth
|
||||
className={isRainbowMode ? rainbowStyles.rainbowSegmentedControl : ''}
|
||||
style={{
|
||||
@ -118,13 +126,18 @@ const TopControls = ({
|
||||
styles={{
|
||||
root: {
|
||||
borderRadius: 9999,
|
||||
maxHeight: '2.6rem',
|
||||
},
|
||||
control: {
|
||||
borderRadius: 9999,
|
||||
},
|
||||
indicator: {
|
||||
borderRadius: 9999,
|
||||
maxHeight: '2rem',
|
||||
},
|
||||
label: {
|
||||
paddingTop: '0rem',
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
@ -41,7 +41,7 @@ export default function ToolPanel() {
|
||||
isRainbowMode ? rainbowStyles.rainbowPaper : ''
|
||||
}`}
|
||||
style={{
|
||||
width: isPanelVisible ? '20rem' : '0',
|
||||
width: isPanelVisible ? '18.5rem' : '0',
|
||||
padding: '0'
|
||||
}}
|
||||
>
|
||||
|
@ -131,7 +131,7 @@ const ToolPicker = ({ selectedToolKey, onSelect, filteredTools, isSearching = fa
|
||||
borderTop: `0.0625rem solid var(--tool-header-border)`,
|
||||
borderBottom: `0.0625rem solid var(--tool-header-border)`,
|
||||
padding: "0.5rem 1rem",
|
||||
fontWeight: 700,
|
||||
fontWeight: 600,
|
||||
background: "var(--tool-header-bg)",
|
||||
color: "var(--tool-header-text)",
|
||||
cursor: "pointer",
|
||||
@ -141,7 +141,7 @@ const ToolPicker = ({ selectedToolKey, onSelect, filteredTools, isSearching = fa
|
||||
}}
|
||||
onClick={() => scrollTo(quickAccessRef)}
|
||||
>
|
||||
<span>{t("toolPicker.quickAccess", "QUICK ACCESS")}</span>
|
||||
<span style={{ fontSize: "1rem" }}>{t("toolPicker.quickAccess", "QUICK ACCESS")}</span>
|
||||
<span
|
||||
style={{
|
||||
background: "var(--tool-header-badge-bg)",
|
||||
@ -156,7 +156,7 @@ const ToolPicker = ({ selectedToolKey, onSelect, filteredTools, isSearching = fa
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<Box ref={quickAccessRef} w="100%">
|
||||
<Box ref={quickAccessRef} w="100%" my="sm">
|
||||
<Stack p="sm" gap="xs">
|
||||
{quickSection?.subcategories.map(sc =>
|
||||
renderToolButtons(t, sc, selectedToolKey, onSelect, false)
|
||||
@ -177,7 +177,7 @@ const ToolPicker = ({ selectedToolKey, onSelect, filteredTools, isSearching = fa
|
||||
borderTop: `0.0625rem solid var(--tool-header-border)`,
|
||||
borderBottom: `0.0625rem solid var(--tool-header-border)`,
|
||||
padding: "0.5rem 1rem",
|
||||
fontWeight: 700,
|
||||
fontWeight: 600,
|
||||
background: "var(--tool-header-bg)",
|
||||
color: "var(--tool-header-text)",
|
||||
cursor: "pointer",
|
||||
@ -187,7 +187,7 @@ const ToolPicker = ({ selectedToolKey, onSelect, filteredTools, isSearching = fa
|
||||
}}
|
||||
onClick={() => scrollTo(allToolsRef)}
|
||||
>
|
||||
<span>{t("toolPicker.allTools", "ALL TOOLS")}</span>
|
||||
<span style={{ fontSize: "1rem" }}>{t("toolPicker.allTools", "ALL TOOLS")}</span>
|
||||
<span
|
||||
style={{
|
||||
background: "var(--tool-header-badge-bg)",
|
||||
|
@ -14,7 +14,6 @@ export interface FileStatusIndicatorProps {
|
||||
|
||||
const FileStatusIndicator = ({
|
||||
selectedFiles = [],
|
||||
placeholder,
|
||||
}: FileStatusIndicatorProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { openFilesModal, onFilesSelect } = useFilesModalContext();
|
||||
|
@ -50,7 +50,7 @@ const renderTooltipTitle = (
|
||||
sidebarTooltip={true}
|
||||
>
|
||||
<Flex align="center" gap="xs" onClick={(e) => e.stopPropagation()}>
|
||||
<Text fw={500} size="lg">
|
||||
<Text fw={400} size="sm">
|
||||
{title}
|
||||
</Text>
|
||||
<LocalIcon icon="gpp-maybe-outline-rounded" width="1.25rem" height="1.25rem" style={{ color: 'var(--icon-files-color)' }} />
|
||||
@ -60,7 +60,7 @@ const renderTooltipTitle = (
|
||||
}
|
||||
|
||||
return (
|
||||
<Text fw={500} size="lg">
|
||||
<Text fw={500} size="sm">
|
||||
{title}
|
||||
</Text>
|
||||
);
|
||||
@ -96,7 +96,7 @@ const ToolStep = ({
|
||||
<div>
|
||||
<div
|
||||
style={{
|
||||
padding: '1rem',
|
||||
padding: '0.5rem',
|
||||
opacity: isCollapsed ? 0.8 : 1,
|
||||
color: isCollapsed ? 'var(--mantine-color-dimmed)' : 'inherit',
|
||||
transition: 'opacity 0.2s ease, color 0.2s ease'
|
||||
@ -114,7 +114,7 @@ const ToolStep = ({
|
||||
>
|
||||
<Flex align="center" gap="sm">
|
||||
{shouldShowNumber && (
|
||||
<Text fw={500} size="lg" c="dimmed">
|
||||
<Text fw={500} size="sm" c="dimmed" mr="0.5rem">
|
||||
{stepNumber}
|
||||
</Text>
|
||||
)}
|
||||
@ -135,7 +135,7 @@ const ToolStep = ({
|
||||
</Flex>
|
||||
|
||||
{!isCollapsed && (
|
||||
<Stack gap="md" pl={_noPadding ? 0 : "md"}>
|
||||
<Stack gap="sm" pl={_noPadding ? 0 : "sm"}>
|
||||
{helpText && (
|
||||
<Text size="sm" c="dimmed">
|
||||
{helpText}
|
||||
@ -145,7 +145,7 @@ const ToolStep = ({
|
||||
</Stack>
|
||||
)}
|
||||
</div>
|
||||
<Divider style={{ marginLeft: '1rem', marginRight: '-0.5rem' }} />
|
||||
<Divider style={{ color: '#E2E8F0', marginLeft: '1rem', marginRight: '-0.5rem' }} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ export const renderToolButtons = (
|
||||
{showSubcategoryHeader && (
|
||||
<SubcategoryHeader label={getSubcategoryLabel(t, subcategory.subcategoryId)} />
|
||||
)}
|
||||
<Stack gap="xs">
|
||||
<div>
|
||||
{subcategory.tools.map(({ id, tool }) => (
|
||||
<ToolButton
|
||||
key={id}
|
||||
@ -29,6 +29,6 @@ export const renderToolButtons = (
|
||||
onSelect={onSelect}
|
||||
/>
|
||||
))}
|
||||
</Stack>
|
||||
</div>
|
||||
</Box>
|
||||
);
|
||||
|
@ -12,8 +12,10 @@ interface ToolButtonProps {
|
||||
rounded?: boolean;
|
||||
}
|
||||
|
||||
const ToolButton: React.FC<ToolButtonProps> = ({ id, tool, isSelected, onSelect, rounded = false }) => {
|
||||
const ToolButton: React.FC<ToolButtonProps> = ({ id, tool, isSelected, onSelect }) => {
|
||||
const isUnavailable = !tool.component && !tool.link;
|
||||
const handleClick = (id: string) => {
|
||||
if (isUnavailable) return;
|
||||
if (tool.link) {
|
||||
// Open external link in new tab
|
||||
window.open(tool.link, '_blank', 'noopener,noreferrer');
|
||||
@ -23,35 +25,30 @@ const ToolButton: React.FC<ToolButtonProps> = ({ id, tool, isSelected, onSelect,
|
||||
onSelect(id);
|
||||
};
|
||||
|
||||
const tooltipContent = isUnavailable
|
||||
? (<span><strong>Coming soon:</strong> {tool.description}</span>)
|
||||
: tool.description;
|
||||
|
||||
return (
|
||||
<Tooltip content={tool.description} position="right" arrow={true} delay={500}>
|
||||
<Tooltip content={tooltipContent} position="right" arrow={true} delay={500}>
|
||||
<Button
|
||||
variant={isSelected ? "filled" : "subtle"}
|
||||
onClick={()=> handleClick(id)}
|
||||
size="md"
|
||||
size="sm"
|
||||
radius="md"
|
||||
leftSection={<div className="tool-button-icon" style={{ color: "var(--tools-text-and-icon-color)" }}>{tool.icon}</div>}
|
||||
fullWidth
|
||||
justify="flex-start"
|
||||
className="tool-button"
|
||||
styles={{
|
||||
root: {
|
||||
borderRadius: rounded ? 'var(--mantine-radius-lg)' : 0,
|
||||
color: "var(--tools-text-and-icon-color)",
|
||||
...(rounded && {
|
||||
'&:hover': {
|
||||
borderRadius: 'var(--mantine-radius-lg)',
|
||||
}
|
||||
})
|
||||
}
|
||||
}}
|
||||
aria-disabled={isUnavailable}
|
||||
styles={{ root: { borderRadius: 0, color: "var(--tools-text-and-icon-color)", cursor: isUnavailable ? 'not-allowed' : undefined } }}
|
||||
>
|
||||
<div className="tool-button-icon" style={{ color: "var(--tools-text-and-icon-color)", marginRight: "0.5rem", transform: "scale(0.8)", transformOrigin: "center", opacity: isUnavailable ? 0.25 : 1 }}>{tool.icon}</div>
|
||||
<FitText
|
||||
text={tool.name}
|
||||
lines={1}
|
||||
minimumFontScale={0.8}
|
||||
as="span"
|
||||
style={{ display: 'inline-block', maxWidth: '100%' }}
|
||||
style={{ display: 'inline-block', maxWidth: '100%', opacity: isUnavailable ? 0.25 : 1 }}
|
||||
/>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
@ -550,12 +550,14 @@ const Viewer = ({
|
||||
justifyContent: "center",
|
||||
pointerEvents: "none",
|
||||
background: "transparent",
|
||||
|
||||
}}
|
||||
>
|
||||
<Paper
|
||||
radius="xl xl 0 0"
|
||||
shadow="sm"
|
||||
p={12}
|
||||
pb={24}
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
|
@ -40,7 +40,7 @@ import OCRSettings from '../components/tools/ocr/OCRSettings';
|
||||
import ConvertSettings from '../components/tools/convert/ConvertSettings';
|
||||
import ChangePermissionsSettings from '../components/tools/changePermissions/ChangePermissionsSettings';
|
||||
|
||||
const showPlaceholderTools = false; // For development purposes. Allows seeing the full list of tools, even if they're unimplemented
|
||||
const showPlaceholderTools = true; // Show all tools; grey out unavailable ones in UI
|
||||
|
||||
// Hook to get the translated tool registry
|
||||
export function useFlatToolRegistry(): ToolRegistry {
|
||||
@ -671,14 +671,13 @@ export function useFlatToolRegistry(): ToolRegistry {
|
||||
|
||||
if (showPlaceholderTools) {
|
||||
return allTools;
|
||||
} else {
|
||||
const filteredTools = Object.keys(allTools)
|
||||
.filter(key => allTools[key].component !== null || allTools[key].link)
|
||||
.reduce((obj, key) => {
|
||||
obj[key] = allTools[key];
|
||||
return obj;
|
||||
}, {} as ToolRegistry);
|
||||
return filteredTools;
|
||||
}
|
||||
const filteredTools = Object.keys(allTools)
|
||||
.filter(key => allTools[key].component !== null || allTools[key].link)
|
||||
.reduce((obj, key) => {
|
||||
obj[key] = allTools[key];
|
||||
return obj;
|
||||
}, {} as ToolRegistry);
|
||||
return filteredTools;
|
||||
}, [t]); // Only re-compute when translations change
|
||||
}
|
||||
|
@ -64,7 +64,9 @@ export function useToolSections(filteredTools: [string /* FIX ME: Should be Tool
|
||||
Object.entries(subs).forEach(([s, tools]) => {
|
||||
const subcategoryId = s as SubcategoryId;
|
||||
if (!quick[subcategoryId]) quick[subcategoryId] = [];
|
||||
quick[subcategoryId].push(...tools);
|
||||
// Only include ready tools (have a component or external link) in Quick Access
|
||||
const readyTools = tools.filter(({ tool }) => tool.component !== null || !!tool.link);
|
||||
quick[subcategoryId].push(...readyTools);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user