Skip to content

Commit b3dac18

Browse files
Rotorsoftrotorsoftclaude
authored
refactor: align betting markets admin components with community market design patterns (#13285)
* refactor: align betting markets admin components with community market design patterns Completed GitHub issue #13274 - Refactored MarketSelector, MarketFilters, MarketCard, and MarketList components to match MarketsAppPage styling - Replaced inline styles and native HTML elements with CW component kit components (CWText, CWButton, CWTag, CWTextInput, CWSelectList, CWCircleMultiplySpinner) - Applied consistent light theme styling: white backgrounds, dark text, light borders matching MarketsAppPage - Implemented proper empty state handling with descriptive CWText messages - Updated grid layout to match MarketsAppPage responsive design (2 columns desktop, 1 mobile) - Added proper status tag color coding and date formatting - Created new SCSS files for MarketSelector and MarketFilters with consistent styling patterns Files changed: - packages/commonwealth/client/scripts/views/components/MarketIntegrations/* (all market integration components) - packages/commonwealth/client/scripts/views/pages/CommunityManagement/Markets/MarketsPage.scss Tests: All unit tests pass, no type errors in modified files, linting passes 🤖 Generated with Claude Code Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Add UI screenshots for PR #13285 --------- Co-authored-by: rotorsoft <rotorsoft@outlook.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 540dd10 commit b3dac18

12 files changed

Lines changed: 347 additions & 144 deletions

File tree

.ai/progress.txt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,35 @@ Each AI run should append an entry with:
7474
* Commit: 3e54e37d98
7575

7676
---
77+
78+
[2026-01-08] Refactor: Refactored betting markets admin components to align with community market design patterns
79+
- Completed GitHub issue #13274
80+
- Key implementation decisions:
81+
* Aligned admin components with MarketsAppPage styling and component patterns (light theme)
82+
* Used CW component kit components (CWText, CWButton, CWTag, CWTextInput, CWSelectList, CWCircleMultiplySpinner)
83+
* Applied light theme styling matching MarketsAppPage: white backgrounds (#ffffff), dark text (#1a1a1a, #212529), light borders (#e9ecef)
84+
* Maintained consistent card styling with hover effects, rounded corners, and gradient provider badges
85+
* Implemented proper empty state handling with descriptive messages
86+
* Used responsive grid layout (2 columns on desktop, 1 on mobile)
87+
* Applied proper status tag color coding (active, new, info)
88+
* Added proper date formatting matching MarketsAppPage patterns
89+
* Replaced inline styles and native HTML elements with CW component kit
90+
- Files changed:
91+
* packages/commonwealth/client/scripts/views/components/MarketIntegrations/MarketSelector.tsx (refactored to use CW components and proper layout)
92+
* packages/commonwealth/client/scripts/views/components/MarketIntegrations/MarketSelector.scss (created new styles matching MarketsAppPage light theme)
93+
* packages/commonwealth/client/scripts/views/components/MarketIntegrations/MarketFilters.tsx (refactored to use CWTextInput and CWSelectList with react-select API)
94+
* packages/commonwealth/client/scripts/views/components/MarketIntegrations/MarketFilters.scss (created responsive filter layout)
95+
* packages/commonwealth/client/scripts/views/components/MarketIntegrations/MarketCard.tsx (refactored to match MarketsAppPage card design with tags, badges, and CWButton)
96+
* packages/commonwealth/client/scripts/views/components/MarketIntegrations/MarketCard.scss (completely rewritten to match MarketsAppPage light theme styling)
97+
* packages/commonwealth/client/scripts/views/components/MarketIntegrations/MarketList.tsx (added proper empty state with CWText)
98+
* packages/commonwealth/client/scripts/views/components/MarketIntegrations/MarketList.scss (updated grid layout and added empty state styles with light theme)
99+
* packages/commonwealth/client/scripts/views/pages/CommunityManagement/Markets/MarketsPage.scss (simplified to match overall structure)
100+
- Tests: All unit tests pass (70 tests in commonwealth package)
101+
- Type checking: No type errors in modified files (pre-existing unrelated errors in model package about Soneium property)
102+
- Linting: All checks pass
103+
- Concerns for reviewers:
104+
* Verify visual consistency between admin and community market views
105+
* Test responsive behavior on mobile devices
106+
* Confirm light theme colors match design system and are consistent
107+
* Validate that status tag colors align with UX expectations
108+
* Check that CWSelectList dropdowns work correctly with react-select API
330 KB
Loading
361 KB
Loading
Lines changed: 76 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,94 @@
1-
@use '../../../styles/shared.scss';
2-
@use '../../../styles/mixins/border_radius';
3-
@use '../../../styles/mixins/colors.module';
4-
@use '../../../styles/mixins/elevation';
5-
61
.market-card {
2+
background: #ffffff;
3+
border-radius: 16px;
4+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
5+
border: 1px solid #e9ecef;
6+
overflow: hidden;
7+
height: 100%;
78
display: flex;
89
flex-direction: column;
9-
justify-content: space-between;
10-
// Override default CWCard styles for a darker theme
11-
border: 1px solid colors.$neutral-700; // Subtle dark border
12-
color: colors.$white; // Light text for contrast
13-
padding: 1rem; // Add back padding that was commented out
14-
height: 100%;
1510

16-
&__image-container {
17-
width: calc(100% + 2rem); // Span full width including padding
18-
margin: -1rem -1rem 1rem -1rem; // Adjust margins to align with card edges
19-
height: 120px; // Fixed height for images
20-
overflow: hidden; // Hide overflow for images
21-
border-top-left-radius: border_radius.$border-radius-md;
22-
border-top-right-radius: border_radius.$border-radius-md;
23-
24-
.market-card__image {
25-
width: 100%;
26-
height: 100%;
27-
object-fit: cover; // Cover the container while maintaining aspect ratio
28-
}
11+
&:hover {
12+
transform: translateY(-4px);
13+
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1);
14+
border-color: #dee2e6;
2915
}
3016

31-
&__header {
32-
margin-bottom: 0.75rem; // Increased margin for spacing
33-
padding-bottom: 0.75rem;
34-
border-bottom: 1px solid colors.$neutral-700; // Darker subtle separator
35-
36-
.CWText {
37-
color: colors.$white; // Ensure title is white
38-
font-size: 1.1rem; // Slightly larger for prominence
39-
}
17+
.market-card-content {
18+
padding: 24px;
19+
display: flex;
20+
flex-direction: column;
21+
height: 100%;
22+
gap: 20px;
4023
}
4124

42-
&__body {
43-
flex-grow: 1;
44-
margin-bottom: 1rem; // Increased margin
45-
font-size: 0.85rem; // Slightly smaller details
46-
color: colors.$neutral-300; // Lighter grey for details
25+
.market-card-header {
26+
display: flex;
27+
justify-content: space-between;
28+
align-items: flex-start;
29+
gap: 12px;
30+
margin-bottom: 4px;
4731

48-
.CWText {
49-
margin-bottom: 0.4rem; // Spacing between details
50-
color: colors.$neutral-300; // Ensure detail text is light grey
51-
}
52-
}
32+
.market-tags {
33+
display: flex;
34+
gap: 8px;
35+
flex-wrap: wrap;
36+
flex: 1;
5337

54-
&__footer {
55-
margin-top: auto;
56-
padding-top: 1rem; // Increased padding
57-
border-top: 1px solid colors.$neutral-700; // Darker subtle separator
38+
.category-tag {
39+
font-size: 12px;
40+
font-weight: 600;
41+
padding: 4px 12px;
42+
border-radius: 6px;
43+
}
5844

59-
button {
60-
width: 100%;
61-
padding: 0.75rem; // More padding for larger button
62-
border-radius: border_radius.$border-radius-md;
63-
border: none; // Remove border, use background color
64-
background-color: colors.$primary-500;
65-
color: colors.$white;
66-
cursor: pointer;
67-
font-weight: 600;
68-
font-size: 0.95rem; // Slightly larger text
45+
.status-tag {
46+
font-size: 11px;
47+
font-weight: 700;
48+
padding: 4px 10px;
49+
border-radius: 6px;
50+
text-transform: uppercase;
51+
letter-spacing: 0.5px;
52+
}
6953

70-
&:hover {
71-
background-color: colors.$primary-600;
54+
.date-tag {
55+
font-size: 11px;
56+
font-weight: 500;
57+
padding: 4px 10px;
58+
border-radius: 6px;
7259
}
60+
}
7361

74-
&:disabled {
75-
background-color: colors.$neutral-700; // Darker disabled background
76-
color: colors.$neutral-500; // Muted disabled text
77-
cursor: not-allowed;
62+
.market-provider {
63+
.provider-badge {
64+
display: inline-block;
65+
padding: 6px 12px;
66+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
67+
color: #ffffff;
68+
border-radius: 8px;
69+
font-size: 11px;
70+
font-weight: 700;
71+
text-transform: uppercase;
72+
letter-spacing: 0.5px;
73+
box-shadow: 0 2px 4px rgba(102, 126, 234, 0.3);
7874
}
7975
}
8076
}
77+
78+
.market-question {
79+
h5 {
80+
color: #212529;
81+
line-height: 1.5;
82+
font-size: 18px;
83+
margin: 0;
84+
}
85+
}
86+
87+
.market-card-footer {
88+
margin-top: auto;
89+
padding-top: 16px;
90+
border-top: 1px solid #e9ecef;
91+
display: flex;
92+
justify-content: flex-end;
93+
}
8194
}
Lines changed: 67 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import React from 'react';
2-
3-
import { CWCard } from 'views/components/component_kit/cw_card';
42
import { CWText } from 'views/components/component_kit/cw_text';
5-
3+
import { CWButton } from 'views/components/component_kit/new_designs/CWButton';
4+
import { CWTag } from 'views/components/component_kit/new_designs/CWTag';
65
import './MarketCard.scss';
76
import { Market } from './types';
87

@@ -27,38 +26,74 @@ export const MarketCard = ({
2726
}
2827
};
2928

29+
const getStatusTagType = (status: string): 'active' | 'new' | 'info' => {
30+
switch (status) {
31+
case 'open':
32+
return 'active';
33+
case 'closed':
34+
return 'new';
35+
case 'settled':
36+
return 'info';
37+
default:
38+
return 'info';
39+
}
40+
};
41+
42+
const formatDate = (date: Date | null) => {
43+
if (!date) return 'N/A';
44+
const dateObj = typeof date === 'string' ? new Date(date) : date;
45+
return new Intl.DateTimeFormat('en-US', {
46+
month: 'short',
47+
day: 'numeric',
48+
year: 'numeric',
49+
}).format(dateObj);
50+
};
51+
3052
return (
31-
<CWCard className="market-card" elevation="elevation-1" interactive>
32-
{market.imageUrl && (
33-
<div className="market-card__image-container">
34-
<img
35-
src={market.imageUrl}
36-
alt={market.question}
37-
className="market-card__image"
38-
/>
53+
<div className="market-card">
54+
<div className="market-card-content">
55+
<div className="market-card-header">
56+
<div className="market-tags">
57+
<CWTag
58+
type="info"
59+
label={market.category}
60+
classNames="category-tag"
61+
/>
62+
<CWTag
63+
type={getStatusTagType(market.status)}
64+
label={market.status.toUpperCase()}
65+
classNames="status-tag"
66+
/>
67+
</div>
68+
<div className="market-provider">
69+
<span className="provider-badge">{market.provider}</span>
70+
</div>
3971
</div>
40-
)}
41-
<div className="market-card__header">
42-
<CWText color="white" fontWeight="semiBold">
43-
{market.question}
44-
</CWText>
45-
</div>
46-
<div className="market-card__body">
47-
<CWText>Provider: {market.provider}</CWText>
48-
<CWText>Category: {market.category}</CWText>
49-
</div>
50-
<div className="market-card__footer">
51-
{isSubscribed ? (
52-
<button
53-
style={{ backgroundColor: 'red' }}
54-
onClick={handleToggleSubscription}
55-
>
56-
Unsubscribe
57-
</button>
58-
) : (
59-
<button onClick={handleToggleSubscription}>Subscribe</button>
72+
73+
<div className="market-question">
74+
<CWText fontWeight="semiBold" type="h5">
75+
{market.question}
76+
</CWText>
77+
</div>
78+
79+
{market.startTime && market.endTime && (
80+
<div className="market-date-chip">
81+
<CWTag
82+
type="info"
83+
label={`From ${formatDate(market.startTime)} to ${formatDate(market.endTime)}`}
84+
classNames="date-tag"
85+
/>
86+
</div>
6087
)}
88+
89+
<div className="market-card-footer">
90+
<CWButton
91+
label={isSubscribed ? 'Unsubscribe' : 'Subscribe'}
92+
onClick={handleToggleSubscription}
93+
buttonType={isSubscribed ? 'destructive' : 'primary'}
94+
/>
95+
</div>
6196
</div>
62-
</CWCard>
97+
</div>
6398
);
6499
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
@use '../../../styles/mixins/media_queries';
2+
3+
.MarketFilters {
4+
display: flex;
5+
flex-direction: column;
6+
gap: 16px;
7+
margin-bottom: 24px;
8+
9+
.filter-search {
10+
width: 100%;
11+
}
12+
13+
.filter-selects {
14+
display: flex;
15+
gap: 16px;
16+
17+
@include media_queries.smallInclusive {
18+
flex-direction: column;
19+
}
20+
21+
> * {
22+
flex: 1;
23+
min-width: 0;
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)