Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 27 additions & 43 deletions src/web-ui/src/app/scenes/miniapps/MiniAppGalleryScene.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
@use '../../../component-library/styles/tokens' as *;

// Gutter aligned with GalleryLayout ($gutter) so the tab strip lines up
// with the page header content of every tab pane.
$scene-gutter: clamp(28px, 4vw, 64px);

.miniapp-gallery-scene {
display: flex;
flex-direction: column;
Expand All @@ -10,56 +14,36 @@
height: 100%;
overflow: hidden;

// Layout glue: make the component-library Tabs fill the scene so each
// pane's GalleryLayout keeps its own internal scroll.
&__tabs {
display: flex;
flex: 0 0 auto;
align-items: center;
gap: 3px;
min-height: 42px;
padding: 6px clamp(24px, 4vw, 56px);
border-bottom: 1px solid var(--border-subtle);
background: var(--color-bg-primary);

button {
display: inline-flex;
align-items: center;
gap: 6px;
min-height: 30px;
padding: 5px 10px;
border: 1px solid transparent;
border-radius: $size-radius-base;
background: transparent;
color: var(--color-text-secondary);
font-size: var(--font-size-sm);
cursor: pointer;

&:hover {
background: var(--element-bg-soft);
color: var(--color-text-primary);
}
flex: 1 1 auto;
min-height: 0;

> .bitfun-tabs__nav {
flex: 0 0 auto;
padding: $size-gap-1 $scene-gutter 0;
background: var(--color-bg-primary);
border-bottom-color: var(--border-subtle);
}

&:active {
transform: translateY(1px);
}
> .bitfun-tabs__content {
display: flex;
flex: 1 1 auto;
min-height: 0;
}

&.is-active {
border-color: var(--border-subtle);
background: var(--element-bg-medium);
color: var(--color-text-primary);
font-weight: 500;
}
.bitfun-tab-pane {
display: flex;
flex: 1 1 auto;
min-width: 0;
min-height: 0;
}
}
}

@media (max-width: 560px) {
.miniapp-gallery-scene__tabs {
justify-content: stretch;
padding-inline: 12px;

button {
justify-content: center;
flex: 1;
}
.miniapp-gallery-scene__tabs > .bitfun-tabs__nav {
padding-inline: $size-gap-3;
}
}
64 changes: 33 additions & 31 deletions src/web-ui/src/app/scenes/miniapps/MiniAppGalleryScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
import React, { Suspense, lazy, useState } from 'react';
import { Download, Store, UploadCloud } from 'lucide-react';
import { Tabs, TabPane } from '@/component-library';
import { useI18n } from '@/infrastructure/i18n';
import './MiniAppGalleryScene.scss';

Expand All @@ -19,40 +20,41 @@ const MiniAppGalleryScene: React.FC = () => {

return (
<div className="miniapp-gallery-scene">
<nav className="miniapp-gallery-scene__tabs" aria-label={t('market.tabs.label')}>
<button
type="button"
className={activeTab === 'installed' ? 'is-active' : undefined}
aria-current={activeTab === 'installed' ? 'page' : undefined}
onClick={() => setActiveTab('installed')}
<Tabs
className="miniapp-gallery-scene__tabs"
type="line"
size="small"
activeKey={activeTab}
onChange={(key) => setActiveTab(key as MiniAppGalleryTab)}
>
<TabPane
tabKey="installed"
icon={<Download size={14} />}
label={t('market.tabs.installed')}
>
<Download size={14} />
{t('market.tabs.installed')}
</button>
<button
type="button"
className={activeTab === 'market' ? 'is-active' : undefined}
aria-current={activeTab === 'market' ? 'page' : undefined}
onClick={() => setActiveTab('market')}
<Suspense fallback={null}>
<MiniAppGalleryView />
</Suspense>
</TabPane>
<TabPane
tabKey="market"
icon={<Store size={14} />}
label={t('market.tabs.market')}
>
<Store size={14} />
{t('market.tabs.market')}
</button>
<button
type="button"
className={activeTab === 'submissions' ? 'is-active' : undefined}
aria-current={activeTab === 'submissions' ? 'page' : undefined}
onClick={() => setActiveTab('submissions')}
<Suspense fallback={null}>
<MiniAppMarketView />
</Suspense>
</TabPane>
<TabPane
tabKey="submissions"
icon={<UploadCloud size={14} />}
label={t('market.tabs.submissions')}
>
<UploadCloud size={14} />
{t('market.tabs.submissions')}
</button>
</nav>
<Suspense fallback={null}>
{activeTab === 'installed' ? <MiniAppGalleryView /> : null}
{activeTab === 'market' ? <MiniAppMarketView /> : null}
{activeTab === 'submissions' ? <MiniAppSubmissionsView /> : null}
</Suspense>
<Suspense fallback={null}>
<MiniAppSubmissionsView />
</Suspense>
</TabPane>
</Tabs>
</div>
);
};
Expand Down
120 changes: 34 additions & 86 deletions src/web-ui/src/app/scenes/miniapps/views/MiniAppMarketView.scss
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
@use '../../../../component-library/styles/tokens' as *;

.miniapp-market-native {
.gallery-page-header,
&__controls,
&__catalog {
width: min(100%, 1240px);
margin-inline: auto;
}

&__header-actions {
display: flex;
align-items: center;
Expand All @@ -24,63 +17,10 @@
gap: $size-gap-1;
color: var(--color-text-secondary);
font-size: var(--font-size-sm);

img {
width: 24px;
height: 24px;
border-radius: $size-radius-full;
}
}

&__controls {
display: flex;
justify-content: space-between;
gap: $size-gap-3;
padding: $size-gap-3 clamp(24px, 4vw, 56px) $size-gap-2;

select {
min-width: 130px;
height: 32px;
padding-inline: $size-gap-2;
border: 1px solid var(--border-subtle);
border-radius: $size-radius-base;
background: var(--element-bg-medium);
color: var(--color-text-primary);
}
}

&__categories {
display: flex;
flex-wrap: wrap;
gap: $size-gap-1;

button {
border: 1px solid transparent;
border-radius: $size-radius-full;
padding: 5px 10px;
background: transparent;
color: var(--color-text-secondary);
cursor: pointer;

&:hover {
background: var(--element-bg-soft);
color: var(--color-text-primary);
}

&.is-active {
border-color: var(--border-base);
background: var(--element-bg-medium);
color: var(--color-text-primary);
}
}
}

&__catalog {
padding: $size-gap-2 clamp(24px, 4vw, 56px) 48px;
}

&__grid {
--gallery-grid-min: 285px;
&__sort {
min-width: 132px;
}

&__load-more {
Expand All @@ -100,22 +40,29 @@
color: inherit;
text-align: left;
cursor: pointer;
transition: transform 160ms ease, border-color 160ms ease, background 160ms ease;
transition:
transform $motion-fast $easing-standard,
border-color $motion-fast $easing-standard,
background $motion-fast $easing-standard;

&:hover {
transform: translateY(-2px);
border-color: var(--border-base);
background: var(--element-bg-soft);
}

&:focus-visible {
outline: 2px solid var(--color-accent-500);
outline-offset: 2px;
}

&__visual {
display: grid;
place-items: center;
aspect-ratio: 16 / 9;
overflow: hidden;
border-bottom: 1px solid var(--border-subtle);
background: var(--color-bg-tertiary);
font-size: 34px;

img {
width: 100%;
Expand All @@ -124,10 +71,18 @@
}
}

&__fallback {
display: grid;
place-items: center;
width: 100%;
height: 100%;
color: var(--color-text-primary);
}

&__body {
display: grid;
gap: 8px;
padding: 14px 15px 15px;
gap: $size-gap-2;
padding: $size-gap-3;

strong {
overflow: hidden;
Expand All @@ -138,7 +93,7 @@

p {
display: -webkit-box;
min-height: 38px;
min-height: 2.9em;
margin: 0;
overflow: hidden;
color: var(--color-text-secondary);
Expand All @@ -162,13 +117,13 @@
}

&__stats {
gap: 13px;
padding-top: 3px;
gap: $size-gap-3;
padding-top: $size-gap-1;

span {
display: inline-flex;
align-items: center;
gap: 4px;
gap: $size-gap-1;
}
}
}
Expand Down Expand Up @@ -229,7 +184,7 @@
&__rating {
display: flex;
align-items: center;
gap: 4px;
gap: $size-gap-1;

button {
display: grid;
Expand All @@ -250,13 +205,13 @@

&__releases {
display: grid;
gap: 6px;
gap: $size-gap-2;

> div {
display: grid;
grid-template-columns: 72px 1fr auto;
align-items: center;
padding: 8px 10px;
padding: $size-gap-2 $size-gap-3;
border: 1px solid var(--border-subtle);
border-radius: $size-radius-base;
color: var(--color-text-secondary);
Expand All @@ -265,20 +220,13 @@
}
}

@media (max-width: 760px) {
.miniapp-market-native {
&__header-actions,
&__controls {
width: 100%;
align-items: stretch;
flex-direction: column;
}
@media (max-width: 720px) {
.miniapp-market-native__header-actions {
width: 100%;
align-items: stretch;
flex-direction: column;

&__header-actions > :first-child {
width: 100%;
}

&__controls select {
> :first-child {
width: 100%;
}
}
Expand Down
Loading