mirror of
https://github.com/mue/mue.git
synced 2026-07-11 18:31:47 +02:00
feat(modal): new navigation with back and forth arrow
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { Suspense, lazy, useState, memo, useEffect } from 'react';
|
||||
import variables from 'config/variables';
|
||||
|
||||
import './scss/index.scss';
|
||||
import ModalLoader from './components/ModalLoader';
|
||||
@@ -21,6 +22,18 @@ function MainModal({ modalClose, deepLinkData }) {
|
||||
// Initialize with deep link tab if provided, otherwise default to settings
|
||||
const initialTab = deepLinkData?.tab || TAB_TYPES.SETTINGS;
|
||||
const [currentTab, setCurrentTab] = useState(initialTab);
|
||||
const [currentSection, setCurrentSection] = useState('');
|
||||
const [productView, setProductView] = useState(null);
|
||||
const [resetDiscoverToAll, setResetDiscoverToAll] = useState(false);
|
||||
const [navigationHistory, setNavigationHistory] = useState([]);
|
||||
const [historyIndex, setHistoryIndex] = useState(-1);
|
||||
const [navigationTrigger, setNavigationTrigger] = useState(null);
|
||||
const [skipNextHistoryAdd, setSkipNextHistoryAdd] = useState(0);
|
||||
|
||||
// Clear product view when changing tabs
|
||||
useEffect(() => {
|
||||
setProductView(null);
|
||||
}, [currentTab]);
|
||||
|
||||
useEffect(() => {
|
||||
// Listen for hash changes while modal is open
|
||||
@@ -33,22 +46,232 @@ function MainModal({ modalClose, deepLinkData }) {
|
||||
return cleanup;
|
||||
}, [currentTab]);
|
||||
|
||||
const addToHistory = (state) => {
|
||||
// Check if this state is different from the current one
|
||||
const currentState = navigationHistory[historyIndex];
|
||||
const isDifferent = !currentState ||
|
||||
currentState.tab !== state.tab ||
|
||||
currentState.section !== state.section ||
|
||||
JSON.stringify(currentState.product) !== JSON.stringify(state.product);
|
||||
|
||||
if (isDifferent) {
|
||||
const newHistory = navigationHistory.slice(0, historyIndex + 1);
|
||||
newHistory.push(state);
|
||||
setNavigationHistory(newHistory);
|
||||
setHistoryIndex(newHistory.length - 1);
|
||||
console.log('Added to history:', state, 'New history:', newHistory);
|
||||
} else {
|
||||
console.log('Skipping duplicate history entry:', state);
|
||||
}
|
||||
};
|
||||
|
||||
const handleChangeTab = (newTab) => {
|
||||
// Only add to history if not navigating via history
|
||||
if (skipNextHistoryAdd === 0) {
|
||||
addToHistory({
|
||||
tab: newTab,
|
||||
section: '',
|
||||
product: null,
|
||||
});
|
||||
} else {
|
||||
setSkipNextHistoryAdd(0); // Reset skip counter
|
||||
}
|
||||
|
||||
setCurrentTab(newTab);
|
||||
// Update URL hash when tab changes
|
||||
updateHash(`#${newTab}`);
|
||||
if (newTab === TAB_TYPES.DISCOVER) {
|
||||
updateHash(`#${newTab}/all`);
|
||||
} else if (newTab === TAB_TYPES.LIBRARY) {
|
||||
updateHash(`#${newTab}/added`);
|
||||
} else {
|
||||
updateHash(`#${newTab}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSectionChange = (section) => {
|
||||
setCurrentSection(section);
|
||||
// Update URL hash when section changes
|
||||
if (currentTab === TAB_TYPES.DISCOVER) {
|
||||
// For Discover tab, update with the section type
|
||||
const sectionMap = {
|
||||
[variables.getMessage('modals.main.marketplace.all')]: 'all',
|
||||
[variables.getMessage('modals.main.marketplace.photo_packs')]: 'photo_packs',
|
||||
[variables.getMessage('modals.main.marketplace.quote_packs')]: 'quote_packs',
|
||||
[variables.getMessage('modals.main.marketplace.preset_settings')]: 'preset_settings',
|
||||
[variables.getMessage('modals.main.marketplace.collections')]: 'collections',
|
||||
};
|
||||
const sectionKey = sectionMap[section];
|
||||
if (sectionKey) {
|
||||
updateHash(`#${currentTab}/${sectionKey}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Don't add section changes to history - they're automatic
|
||||
// Only track user-initiated navigation (tab switches and product views)
|
||||
};
|
||||
|
||||
const handleProductView = (product) => {
|
||||
setProductView(product);
|
||||
|
||||
// Add to navigation history only if not skipping
|
||||
// Store only essential product info, not full object
|
||||
if (product && skipNextHistoryAdd === 0) {
|
||||
addToHistory({
|
||||
tab: currentTab,
|
||||
section: currentSection,
|
||||
product: {
|
||||
type: product.type,
|
||||
name: product.name,
|
||||
id: product.id,
|
||||
},
|
||||
});
|
||||
} else if (skipNextHistoryAdd > 0) {
|
||||
console.log('Skipping product view history add');
|
||||
setSkipNextHistoryAdd(0); // Reset after use
|
||||
}
|
||||
};
|
||||
|
||||
const handleResetDiscoverToAll = () => {
|
||||
setResetDiscoverToAll(true);
|
||||
setTimeout(() => setResetDiscoverToAll(false), 100);
|
||||
};
|
||||
|
||||
const handleBack = () => {
|
||||
if (historyIndex > 0) {
|
||||
const newIndex = historyIndex - 1;
|
||||
const previousState = navigationHistory[newIndex];
|
||||
console.log('Going back to:', previousState);
|
||||
|
||||
setHistoryIndex(newIndex);
|
||||
|
||||
// Set skip flag BEFORE changing any state
|
||||
setSkipNextHistoryAdd(1);
|
||||
|
||||
// Change tab if different
|
||||
if (previousState.tab !== currentTab) {
|
||||
setCurrentTab(previousState.tab);
|
||||
}
|
||||
|
||||
setCurrentSection(previousState.section);
|
||||
setProductView(previousState.product);
|
||||
|
||||
// Trigger navigation in child components
|
||||
if (previousState.product) {
|
||||
// Viewing a product
|
||||
setNavigationTrigger({
|
||||
type: 'product',
|
||||
data: previousState.product,
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
updateHash(`#${previousState.tab}/${previousState.product.type}/${previousState.product.id}`);
|
||||
} else {
|
||||
// Viewing main view
|
||||
setNavigationTrigger({
|
||||
type: 'main',
|
||||
data: null,
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
if (previousState.tab === TAB_TYPES.DISCOVER) {
|
||||
const sectionMap = {
|
||||
[variables.getMessage('modals.main.marketplace.all')]: 'all',
|
||||
[variables.getMessage('modals.main.marketplace.photo_packs')]: 'photo_packs',
|
||||
[variables.getMessage('modals.main.marketplace.quote_packs')]: 'quote_packs',
|
||||
[variables.getMessage('modals.main.marketplace.preset_settings')]: 'preset_settings',
|
||||
[variables.getMessage('modals.main.marketplace.collections')]: 'collections',
|
||||
};
|
||||
const sectionKey = sectionMap[previousState.section] || 'all';
|
||||
updateHash(`#${previousState.tab}/${sectionKey}`);
|
||||
} else if (previousState.tab === TAB_TYPES.LIBRARY) {
|
||||
updateHash(`#${previousState.tab}/added`);
|
||||
} else {
|
||||
updateHash(`#${previousState.tab}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleForward = () => {
|
||||
if (historyIndex < navigationHistory.length - 1) {
|
||||
const newIndex = historyIndex + 1;
|
||||
const nextState = navigationHistory[newIndex];
|
||||
console.log('Going forward to:', nextState);
|
||||
|
||||
setHistoryIndex(newIndex);
|
||||
|
||||
// Set skip flag BEFORE changing any state
|
||||
setSkipNextHistoryAdd(1);
|
||||
|
||||
// Change tab if different
|
||||
if (nextState.tab !== currentTab) {
|
||||
setCurrentTab(nextState.tab);
|
||||
}
|
||||
|
||||
setCurrentSection(nextState.section);
|
||||
setProductView(nextState.product);
|
||||
|
||||
// Trigger navigation in child components
|
||||
if (nextState.product) {
|
||||
setNavigationTrigger({
|
||||
type: 'product',
|
||||
data: nextState.product,
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
updateHash(`#${nextState.tab}/${nextState.product.type}/${nextState.product.id}`);
|
||||
} else {
|
||||
setNavigationTrigger({
|
||||
type: 'main',
|
||||
data: null,
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
if (nextState.tab === TAB_TYPES.DISCOVER) {
|
||||
const sectionMap = {
|
||||
[variables.getMessage('modals.main.marketplace.all')]: 'all',
|
||||
[variables.getMessage('modals.main.marketplace.photo_packs')]: 'photo_packs',
|
||||
[variables.getMessage('modals.main.marketplace.quote_packs')]: 'quote_packs',
|
||||
[variables.getMessage('modals.main.marketplace.preset_settings')]: 'preset_settings',
|
||||
[variables.getMessage('modals.main.marketplace.collections')]: 'collections',
|
||||
};
|
||||
const sectionKey = sectionMap[nextState.section] || 'all';
|
||||
updateHash(`#${nextState.tab}/${sectionKey}`);
|
||||
} else if (nextState.tab === TAB_TYPES.LIBRARY) {
|
||||
updateHash(`#${nextState.tab}/added`);
|
||||
} else {
|
||||
updateHash(`#${nextState.tab}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const canGoBack = historyIndex > 0;
|
||||
const canGoForward = historyIndex < navigationHistory.length - 1;
|
||||
|
||||
const TabComponent = TAB_COMPONENTS[currentTab] || Settings;
|
||||
|
||||
return (
|
||||
<div className="frame">
|
||||
<ModalTopBar currentTab={currentTab} onTabChange={handleChangeTab} onClose={modalClose} />
|
||||
<ModalTopBar
|
||||
currentTab={currentTab}
|
||||
currentSection={currentSection}
|
||||
productView={productView}
|
||||
onTabChange={handleChangeTab}
|
||||
onClose={modalClose}
|
||||
onBack={handleBack}
|
||||
onForward={handleForward}
|
||||
canGoBack={canGoBack}
|
||||
canGoForward={canGoForward}
|
||||
/>
|
||||
<Suspense fallback={<ModalLoader />}>
|
||||
<TabComponent
|
||||
changeTab={handleChangeTab}
|
||||
deepLinkData={deepLinkData}
|
||||
currentTab={currentTab}
|
||||
onSectionChange={handleSectionChange}
|
||||
onProductView={handleProductView}
|
||||
resetToAll={resetDiscoverToAll}
|
||||
onResetToAll={handleResetDiscoverToAll}
|
||||
navigationTrigger={navigationTrigger}
|
||||
/>
|
||||
</Suspense>
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import variables from 'config/variables';
|
||||
import { useState } from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
import Tab from './Tab';
|
||||
import ReminderInfo from '../components/ReminderInfo';
|
||||
import ErrorBoundary from '../../../../features/misc/modals/ErrorBoundary';
|
||||
import { TAB_TYPES } from '../constants/tabConfig';
|
||||
|
||||
const Tabs = ({ children, navbar = false, currentTab: activeTab }) => {
|
||||
const Tabs = ({ children, navbar = false, currentTab: activeTab, onSectionChange, resetToFirst }) => {
|
||||
const [currentTab, setCurrentTab] = useState(children[0]?.props.label);
|
||||
const [currentName, setCurrentName] = useState(children[0]?.props.name);
|
||||
const [showReminder, setShowReminder] = useState(localStorage.getItem('showReminder') === 'true');
|
||||
@@ -17,8 +17,31 @@ const Tabs = ({ children, navbar = false, currentTab: activeTab }) => {
|
||||
|
||||
setCurrentTab(tab);
|
||||
setCurrentName(name);
|
||||
|
||||
// Notify parent of section change
|
||||
if (onSectionChange) {
|
||||
onSectionChange(tab);
|
||||
}
|
||||
};
|
||||
|
||||
// Notify parent of initial section on mount
|
||||
useEffect(() => {
|
||||
if (onSectionChange && currentTab) {
|
||||
onSectionChange(currentTab);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Reset to first tab when requested
|
||||
useEffect(() => {
|
||||
if (resetToFirst) {
|
||||
setCurrentTab(children[0]?.props.label);
|
||||
setCurrentName(children[0]?.props.name);
|
||||
if (onSectionChange) {
|
||||
onSectionChange(children[0]?.props.label);
|
||||
}
|
||||
}
|
||||
}, [resetToFirst]);
|
||||
|
||||
const handleHideReminder = () => {
|
||||
localStorage.setItem('showReminder', 'false');
|
||||
setShowReminder(false);
|
||||
|
||||
@@ -1,18 +1,121 @@
|
||||
import variables from 'config/variables';
|
||||
import { MdClose } from 'react-icons/md';
|
||||
import { MdClose, MdChevronRight, MdArrowBack, MdArrowForward } from 'react-icons/md';
|
||||
import { Tooltip, Button } from 'components/Elements';
|
||||
import { NAVBAR_BUTTONS } from '../constants/tabConfig';
|
||||
|
||||
function ModalTopBar({ currentTab, onTabChange, onClose }) {
|
||||
// Map marketplace types to translation keys
|
||||
const MARKETPLACE_TYPE_TO_KEY = {
|
||||
photo_packs: 'modals.main.marketplace.photo_packs',
|
||||
photos: 'modals.main.marketplace.photo_packs',
|
||||
quote_packs: 'modals.main.marketplace.quote_packs',
|
||||
quotes: 'modals.main.marketplace.quote_packs',
|
||||
preset_settings: 'modals.main.marketplace.preset_settings',
|
||||
settings: 'modals.main.marketplace.preset_settings',
|
||||
collections: 'modals.main.marketplace.collections',
|
||||
all: 'modals.main.marketplace.all',
|
||||
};
|
||||
|
||||
function ModalTopBar({
|
||||
currentTab,
|
||||
currentSection,
|
||||
productView,
|
||||
onTabChange,
|
||||
onClose,
|
||||
onBack,
|
||||
onForward,
|
||||
canGoBack,
|
||||
canGoForward,
|
||||
}) {
|
||||
// Get the current tab label
|
||||
const currentTabButton = NAVBAR_BUTTONS.find(({ tab }) => tab === currentTab);
|
||||
const currentTabLabel = currentTabButton
|
||||
? variables.getMessage(currentTabButton.messageKey)
|
||||
: '';
|
||||
|
||||
// Determine breadcrumb path with click handlers
|
||||
const breadcrumbPath = [];
|
||||
|
||||
if (currentTabLabel) {
|
||||
breadcrumbPath.push({
|
||||
label: currentTabLabel,
|
||||
onClick: productView ? productView.onBackToAll : null, // Clickable if viewing a product
|
||||
});
|
||||
|
||||
if (productView) {
|
||||
// Show: Discover > Category > Product
|
||||
const categoryKey = MARKETPLACE_TYPE_TO_KEY[productView.type];
|
||||
if (categoryKey) {
|
||||
breadcrumbPath.push({
|
||||
label: variables.getMessage(categoryKey),
|
||||
onClick: productView.onBack || null,
|
||||
});
|
||||
}
|
||||
breadcrumbPath.push({
|
||||
label: productView.name,
|
||||
onClick: null, // Current item - not clickable
|
||||
});
|
||||
} else if (currentSection) {
|
||||
// Show: Tab > Section
|
||||
breadcrumbPath.push({
|
||||
label: currentSection,
|
||||
onClick: null, // Current section - not clickable
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="modalTopBar">
|
||||
<div className="topBarLeft">
|
||||
<div className="navigationButtons">
|
||||
<Tooltip title="Back" key="backTooltip">
|
||||
<button
|
||||
className="navButton"
|
||||
onClick={onBack}
|
||||
disabled={!canGoBack}
|
||||
aria-label="Navigate back"
|
||||
>
|
||||
<MdArrowBack />
|
||||
</button>
|
||||
</Tooltip>
|
||||
<Tooltip title="Forward" key="forwardTooltip">
|
||||
<button
|
||||
className="navButton"
|
||||
onClick={onForward}
|
||||
disabled={!canGoForward}
|
||||
aria-label="Navigate forward"
|
||||
>
|
||||
<MdArrowForward />
|
||||
</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<img
|
||||
src="src/assets/icons/mue_about.png"
|
||||
alt="Mue"
|
||||
className="topBarLogo"
|
||||
draggable={false}
|
||||
/>
|
||||
{breadcrumbPath.length > 0 && (
|
||||
<div className="breadcrumbs">
|
||||
{breadcrumbPath.map((item, index) => {
|
||||
const isLast = index === breadcrumbPath.length - 1;
|
||||
const isClickable = item.onClick !== null;
|
||||
|
||||
return (
|
||||
<span key={index} className="breadcrumb-segment">
|
||||
<span
|
||||
className={`breadcrumb-item ${isLast ? 'breadcrumb-current' : ''} ${
|
||||
isClickable ? 'breadcrumb-clickable' : ''
|
||||
}`}
|
||||
onClick={item.onClick}
|
||||
>
|
||||
{item.label}
|
||||
</span>
|
||||
{!isLast && <MdChevronRight className="breadcrumb-separator" />}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="topBarRight">
|
||||
<div className="topBarNavigation">
|
||||
|
||||
@@ -11,11 +11,94 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
gap: 1rem;
|
||||
|
||||
.navigationButtons {
|
||||
display: flex;
|
||||
gap: 0.25rem;
|
||||
|
||||
.navButton {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
padding: 0.5rem;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background: none;
|
||||
transition: 0.3s;
|
||||
|
||||
@include themed {
|
||||
color: t($color);
|
||||
}
|
||||
|
||||
svg {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
@include themed {
|
||||
background: t($modal-sidebarActive);
|
||||
}
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.3;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.topBarLogo {
|
||||
height: 32px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.breadcrumbs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0;
|
||||
font-size: 0.95rem;
|
||||
font-weight: 500;
|
||||
|
||||
.breadcrumb-segment {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
// gap: 0.5rem;
|
||||
}
|
||||
|
||||
.breadcrumb-item {
|
||||
@include themed {
|
||||
color: t($subColor);
|
||||
}
|
||||
white-space: nowrap;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.breadcrumb-clickable {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.7;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.breadcrumb-separator {
|
||||
@include themed {
|
||||
color: t($subColor);
|
||||
}
|
||||
opacity: 0.5;
|
||||
font-size: 1.2rem;
|
||||
margin: 0 0.25rem;
|
||||
}
|
||||
|
||||
.breadcrumb-current {
|
||||
@include themed {
|
||||
color: t($color);
|
||||
}
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.topBarRight {
|
||||
|
||||
@@ -147,7 +147,24 @@ class Marketplace extends PureComponent {
|
||||
|
||||
// Update URL hash with item ID for deep linking
|
||||
if (info.data?.id) {
|
||||
updateHash(`#marketplace/${info.data.type}/${info.data.id}`);
|
||||
updateHash(`#discover/${info.data.type}/${info.data.id}`);
|
||||
}
|
||||
|
||||
// Notify parent about product view for breadcrumbs
|
||||
if (this.props.onProductView) {
|
||||
this.props.onProductView({
|
||||
id: info.data.id,
|
||||
type: info.data.type,
|
||||
name: info.data.display_name || info.data.name,
|
||||
onBack: () => this.toggle('main'),
|
||||
onBackToAll: () => {
|
||||
this.toggle('main');
|
||||
updateHash('#discover/all');
|
||||
if (this.props.onResetToAll) {
|
||||
this.props.onResetToAll();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
document.querySelector('#modal').scrollTop = 0;
|
||||
@@ -171,11 +188,16 @@ class Marketplace extends PureComponent {
|
||||
});
|
||||
|
||||
// Update hash for collection deep linking
|
||||
updateHash(`#marketplace/collection/${data}`);
|
||||
updateHash(`#discover/collection/${data}`);
|
||||
} else {
|
||||
this.setState({ item: {}, relatedItems: [] });
|
||||
// Clear hash when returning to main view
|
||||
updateHash('#marketplace');
|
||||
updateHash(`#discover/${this.props.type}`);
|
||||
|
||||
// Clear product view for breadcrumbs
|
||||
if (this.props.onProductView) {
|
||||
this.props.onProductView(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,6 +353,21 @@ class Marketplace extends PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
// Handle navigation trigger changes
|
||||
if (this.props.navigationTrigger && this.props.navigationTrigger !== prevProps.navigationTrigger) {
|
||||
const { type, data } = this.props.navigationTrigger;
|
||||
|
||||
if (type === 'product' && data) {
|
||||
// Navigate to product
|
||||
this.toggle('item', { id: data.id, type: data.type });
|
||||
} else if (type === 'main' || type === 'section') {
|
||||
// Navigate to main view (browse/listing page)
|
||||
this.toggle('main');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
// stop making requests
|
||||
this.controller.abort();
|
||||
|
||||
@@ -185,7 +185,7 @@ class ItemPage extends PureComponent {
|
||||
modalClose={() => this.setState({ shareModal: false })}
|
||||
/>
|
||||
</Modal>
|
||||
<Header
|
||||
{/* <Header
|
||||
title={
|
||||
this.props.addons
|
||||
? variables.getMessage('modals.main.addons.added')
|
||||
@@ -200,7 +200,7 @@ class ItemPage extends PureComponent {
|
||||
}
|
||||
report={false}
|
||||
goBack={this.props.toggleFunction}
|
||||
/>
|
||||
/> */}
|
||||
<div className="itemPage">
|
||||
<div className="itemShowcase">
|
||||
<div className="subHeader">
|
||||
|
||||
@@ -4,26 +4,71 @@ import { memo } from 'react';
|
||||
import Tabs from '../../../components/Elements/MainModal/backend/Tabs';
|
||||
import MarketplaceTab from '../../marketplace/views/Browse';
|
||||
|
||||
function Discover({ changeTab, deepLinkData, currentTab }) {
|
||||
function Discover({
|
||||
changeTab,
|
||||
deepLinkData,
|
||||
currentTab,
|
||||
onSectionChange,
|
||||
onProductView,
|
||||
resetToAll,
|
||||
onResetToAll,
|
||||
navigationTrigger,
|
||||
}) {
|
||||
return (
|
||||
<Tabs changeTab={(type) => changeTab(type)} current="discover" currentTab={currentTab}>
|
||||
<Tabs
|
||||
changeTab={(type) => changeTab(type)}
|
||||
current="discover"
|
||||
currentTab={currentTab}
|
||||
onSectionChange={onSectionChange}
|
||||
resetToFirst={resetToAll}
|
||||
>
|
||||
<div label={variables.getMessage('modals.main.marketplace.all')} name="all">
|
||||
<MarketplaceTab type="all" deepLinkData={deepLinkData} />
|
||||
<MarketplaceTab
|
||||
type="all"
|
||||
deepLinkData={deepLinkData}
|
||||
onProductView={onProductView}
|
||||
onResetToAll={onResetToAll}
|
||||
navigationTrigger={navigationTrigger}
|
||||
/>
|
||||
</div>
|
||||
<div label={variables.getMessage('modals.main.marketplace.photo_packs')} name="photo_packs">
|
||||
<MarketplaceTab type="photo_packs" deepLinkData={deepLinkData} />
|
||||
<MarketplaceTab
|
||||
type="photo_packs"
|
||||
deepLinkData={deepLinkData}
|
||||
onProductView={onProductView}
|
||||
onResetToAll={onResetToAll}
|
||||
navigationTrigger={navigationTrigger}
|
||||
/>
|
||||
</div>
|
||||
<div label={variables.getMessage('modals.main.marketplace.quote_packs')} name="quote_packs">
|
||||
<MarketplaceTab type="quote_packs" deepLinkData={deepLinkData} />
|
||||
<MarketplaceTab
|
||||
type="quote_packs"
|
||||
deepLinkData={deepLinkData}
|
||||
onProductView={onProductView}
|
||||
onResetToAll={onResetToAll}
|
||||
navigationTrigger={navigationTrigger}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
label={variables.getMessage('modals.main.marketplace.preset_settings')}
|
||||
name="preset_settings"
|
||||
>
|
||||
<MarketplaceTab type="preset_settings" deepLinkData={deepLinkData} />
|
||||
<MarketplaceTab
|
||||
type="preset_settings"
|
||||
deepLinkData={deepLinkData}
|
||||
onProductView={onProductView}
|
||||
onResetToAll={onResetToAll}
|
||||
navigationTrigger={navigationTrigger}
|
||||
/>
|
||||
</div>
|
||||
<div label={variables.getMessage('modals.main.marketplace.collections')} name="collections">
|
||||
<MarketplaceTab type="collections" deepLinkData={deepLinkData} />
|
||||
<MarketplaceTab
|
||||
type="collections"
|
||||
deepLinkData={deepLinkData}
|
||||
onProductView={onProductView}
|
||||
onResetToAll={onResetToAll}
|
||||
navigationTrigger={navigationTrigger}
|
||||
/>
|
||||
</div>
|
||||
</Tabs>
|
||||
);
|
||||
|
||||
@@ -7,7 +7,12 @@ import Create from '../../marketplace/views/Create';
|
||||
|
||||
function Library(props) {
|
||||
return (
|
||||
<Tabs changeTab={(type) => props.changeTab(type)} current="library" currentTab={props.currentTab}>
|
||||
<Tabs
|
||||
changeTab={(type) => props.changeTab(type)}
|
||||
current="library"
|
||||
currentTab={props.currentTab}
|
||||
onSectionChange={props.onSectionChange}
|
||||
>
|
||||
<div label={variables.getMessage('modals.main.addons.added')} name="added">
|
||||
<Added />
|
||||
</div>
|
||||
|
||||
@@ -90,7 +90,12 @@ const sections = [
|
||||
|
||||
function Settings(props) {
|
||||
return (
|
||||
<Tabs changeTab={(type) => props.changeTab(type)} current="settings" currentTab={props.currentTab}>
|
||||
<Tabs
|
||||
changeTab={(type) => props.changeTab(type)}
|
||||
current="settings"
|
||||
currentTab={props.currentTab}
|
||||
onSectionChange={props.onSectionChange}
|
||||
>
|
||||
{sections.map(({ label, name, component: Component }) => (
|
||||
<div key={name} label={variables.getMessage(label)} name={name}>
|
||||
<Component />
|
||||
|
||||
Reference in New Issue
Block a user