@liiift-studio/sales-portal 3.1.4 → 3.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -67,6 +67,7 @@ export default function Insights({
67
67
  let grossRevenue, netRevenue, orderCount, averageOrderValue, discountTotal, discountRate, refundTotal, refundRate;
68
68
  let topLocation = 'Unknown', topLocationPercentage = 0, locationChange = null;
69
69
  let hasPreviousData = false;
70
+ let previousRevenue = 0, previousOrderCount = 0, previousAvgOrderValue = 0, previousRefundTotal = 0;
70
71
  let revenueChange = null, orderCountChange = null, avgOrderValueChange = null, refundChange = null;
71
72
 
72
73
  if (isYearView) {
@@ -113,11 +114,6 @@ export default function Insights({
113
114
  locationChange = locData.locationChange ?? null;
114
115
 
115
116
  // Calculate previous period metrics (if available)
116
- let previousRevenue = 0;
117
- let previousOrderCount = 0;
118
- let previousAvgOrderValue = 0;
119
- let previousRefundTotal = 0;
120
-
121
117
  if (previousSales && previousSales.length > 0) {
122
118
  hasPreviousData = true;
123
119
  previousOrderCount = previousSales.length;
@@ -167,21 +163,21 @@ export default function Insights({
167
163
  title: 'Gross Sales',
168
164
  value: formatCurrency(grossRevenue),
169
165
  change: revenueChange,
170
- tooltip: isYearView ? `${year} year total` : hasPreviousData ? 'vs prior month' : 'No prior data available',
166
+ tooltip: isYearView ? `${year} year total` : hasPreviousData ? `Previous: ${formatCurrency(previousRevenue)}` : 'No prior data available',
171
167
  bgcolor: '#000000',
172
168
  },
173
169
  {
174
170
  title: 'Orders',
175
171
  value: orderCount,
176
172
  change: orderCountChange,
177
- tooltip: isYearView ? `${year} year total` : hasPreviousData ? 'vs prior month' : 'No prior data available',
173
+ tooltip: isYearView ? `${year} year total` : hasPreviousData ? `Previous: ${previousOrderCount}` : 'No prior data available',
178
174
  bgcolor: '#000000',
179
175
  },
180
176
  {
181
177
  title: 'Avg. Order Value',
182
178
  value: formatCurrency(averageOrderValue),
183
179
  change: avgOrderValueChange,
184
- tooltip: isYearView ? `${year} year average` : hasPreviousData ? 'vs prior month' : 'No prior data available',
180
+ tooltip: isYearView ? `${year} year average` : hasPreviousData ? `Previous: ${formatCurrency(previousAvgOrderValue)}` : 'No prior data available',
185
181
  bgcolor: '#000000',
186
182
  },
187
183
  {
@@ -253,6 +249,7 @@ export default function Insights({
253
249
  sx={{
254
250
  display: 'flex',
255
251
  flexWrap: 'wrap',
252
+ width: '100%',
256
253
  gap: isMobile ? 1.5 : 2,
257
254
  mt: 2,
258
255
  position: 'relative',
@@ -112,16 +112,6 @@ export default function YearOverview({ data, loading = false, error = '', year,
112
112
 
113
113
  return (
114
114
  <Box sx={{ width: '100%' }}>
115
- {/* Year total */}
116
- <Typography variant="h6" sx={{ mb: 2, opacity: 0.7 }}>
117
- {year} Total: {symbol}{(data.yearTotal / 100).toLocaleString('en-US', { minimumFractionDigits: 2 })}
118
- {data.yearShipping > 0 && (
119
- <span style={{ opacity: 0.5, fontSize: '0.8em' }}>
120
- {' '}(+ {symbol}{(data.yearShipping / 100).toLocaleString('en-US', { minimumFractionDigits: 2 })} shipping)
121
- </span>
122
- )}
123
- </Typography>
124
-
125
115
  {/* Stacked bar chart */}
126
116
  {series.length > 0 ? (
127
117
  <Box sx={{ width: '100%', height: { xs: 200, sm: 300, md: 350 } }}>
@@ -176,35 +166,63 @@ export default function YearOverview({ data, loading = false, error = '', year,
176
166
  )}
177
167
 
178
168
  {/* Monthly breakdown table */}
179
- <Box sx={{ mt: 4, opacity: 0.8 }}>
169
+ <Box sx={{
170
+ mt: 4,
171
+ mb: 6,
172
+ opacity: 0.8,
173
+ display: 'grid',
174
+ gridTemplateColumns: 'auto auto auto',
175
+ columnGap: { xs: 3, sm: 4 },
176
+ width: 'fit-content',
177
+ }}>
180
178
  {data.months.map((m, i) => (
181
- <Box
182
- key={i}
183
- onClick={() => onMonthClick && onMonthClick(i)}
184
- sx={{
185
- display: 'flex',
186
- justifyContent: 'space-between',
187
- py: { xs: 1.5, sm: 0.75 },
188
- px: { xs: 1.5, sm: 1 },
189
- borderBottom: '1px solid rgba(0,0,0,0.06)',
190
- cursor: 'pointer',
191
- '&:hover': { bgcolor: 'rgba(0,0,0,0.03)' },
192
- borderRadius: '4px',
193
- }}
194
- >
195
- <Typography variant="body2">
179
+ <React.Fragment key={i}>
180
+ <Typography
181
+ variant="body2"
182
+ onClick={() => onMonthClick && onMonthClick(i)}
183
+ sx={{
184
+ py: { xs: 1.5, sm: 0.75 },
185
+ pl: { xs: 1.5, sm: 1 },
186
+ cursor: 'pointer',
187
+ borderBottom: '1px solid rgba(0,0,0,0.06)',
188
+ '&:hover': { bgcolor: 'rgba(0,0,0,0.03)' },
189
+ borderRadius: '4px 0 0 4px',
190
+ }}
191
+ >
196
192
  {MONTH_LABELS[i]} {year}
197
193
  {m.error && <span style={{ color: 'var(--red, red)', marginLeft: 8 }}>error</span>}
198
194
  </Typography>
199
- <Box sx={{ display: 'flex', gap: { xs: 1.5, sm: 3 } }}>
200
- <Typography variant="body2" sx={{ opacity: 0.5 }}>
201
- {m.salesCount} sale{m.salesCount !== 1 ? 's' : ''}
202
- </Typography>
203
- <Typography variant="body2" sx={{ fontWeight: 'bold' }}>
204
- {symbol}{(m.total / 100).toLocaleString('en-US', { minimumFractionDigits: 2 })}
205
- </Typography>
206
- </Box>
207
- </Box>
195
+ <Typography
196
+ variant="body2"
197
+ onClick={() => onMonthClick && onMonthClick(i)}
198
+ sx={{
199
+ py: { xs: 1.5, sm: 0.75 },
200
+ opacity: 0.5,
201
+ textAlign: 'right',
202
+ cursor: 'pointer',
203
+ borderBottom: '1px solid rgba(0,0,0,0.06)',
204
+ '&:hover': { bgcolor: 'rgba(0,0,0,0.03)' },
205
+ }}
206
+ >
207
+ {m.salesCount} sale{m.salesCount !== 1 ? 's' : ''}
208
+ </Typography>
209
+ <Typography
210
+ variant="body2"
211
+ onClick={() => onMonthClick && onMonthClick(i)}
212
+ sx={{
213
+ py: { xs: 1.5, sm: 0.75 },
214
+ pr: { xs: 1.5, sm: 1 },
215
+ fontWeight: 'bold',
216
+ textAlign: 'right',
217
+ cursor: 'pointer',
218
+ borderBottom: '1px solid rgba(0,0,0,0.06)',
219
+ '&:hover': { bgcolor: 'rgba(0,0,0,0.03)' },
220
+ borderRadius: '0 4px 4px 0',
221
+ }}
222
+ >
223
+ {symbol}{(m.total / 100).toLocaleString('en-US', { minimumFractionDigits: 2 })}
224
+ </Typography>
225
+ </React.Fragment>
208
226
  ))}
209
227
  </Box>
210
228
  </Box>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liiift-studio/sales-portal",
3
- "version": "3.1.4",
3
+ "version": "3.1.5",
4
4
  "description": "Centralized sales portal package for Liiift Studio projects",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",