feat(analytics): add stale inventory and profit forecast dashboard#130
Conversation
|
@shivi14112007-create is attempting to deploy a commit to the participationcorner2025-8967's projects Team on Vercel. A member of the Team first needs to authorize it. |
📝 SummaryThe provided pull request diff introduces a new analytics page with two main components: 📂 Files Changed
🎭 Code PoemAnalytics page is now in sight, 🚨 Bugs & Architectural Violations* The `StaleInventoryCard` component uses `any` as the type for the `items` prop, which should be replaced with a more specific type. * The `loader` function in `analytics.tsx` uses `prisma.inventoryItem.findMany` to fetch data, but it does not handle errors properly. It should be updated to handle potential errors and provide a fallback or error message. * The `ProfitForecast` component uses `toFixed(2)` to format numbers, but it does not handle cases where the number is `null` or `undefined`. It should be updated to handle these cases and provide a default value or error message. * The `StaleInventoryCard` component uses `Math.floor` to calculate the days in stock, but it does not handle cases where the purchase date is `null` or `undefined`. It should be updated to handle these cases and provide a default value or error message. * The `analytics.tsx` file uses `const prisma = new PrismaClient();` to create a new Prisma client instance, but it does not handle cases where the Prisma client is not properly configured. It should be updated to handle these cases and provide a fallback or error message. Looks solid in terms of architectural rules, as it uses Remix, Prisma, and Vanilla CSS Modules, and places UI components in the correct directory.💡 Suggestions & Best Practices* Consider adding more specific types for the `items` prop in the `StaleInventoryCard` component. * Update the `loader` function in `analytics.tsx` to handle potential errors and provide a fallback or error message. * Consider using a more robust formatting library, such as ` numeral.js`, to format numbers in the `ProfitForecast` component. * Update the `StaleInventoryCard` component to handle cases where the purchase date is `null` or `undefined`. * Consider using a more robust way to create a Prisma client instance, such as using a singleton pattern or a dependency injection framework. * Consider adding more tests to cover the new components and functionality. * Consider using a linter and a code formatter to ensure consistency and readability in the codebase. |
|
Amazing work on this! I love how you structured the Prisma query. Using the nested There is just one tiny thing missing before we can merge this: Could you please open Once you push that final commit, I'll approve and merge this immediately! Great job on your first PR! |
📝 SummaryThe provided pull request diff introduces several changes to the FlipTrack application, including the addition of a new analytics page, updates to the app sidebar, and the creation of new UI components for profit forecasting and stale inventory tracking. 📂 Files Changed
🎭 Code PoemChanges abound, with updates so fine, 🚨 Bugs & Architectural Violations* The `app/blocks/analytics/ProfitForecast.tsx` and `app/blocks/analytics/StaleInventoryCard.tsx` components are placed in the correct directory, following the rule of placing UI components in the `app/blocks/` directory. * The use of Vanilla CSS Modules is consistent throughout the changes, with no evidence of Tailwind CSS classes. * However, the `app/routes/analytics.tsx` file uses `PrismaClient` directly, which might be a potential issue if not handled properly. It's recommended to use a wrapper or a service layer to interact with the database. * The `loader` function in `app/routes/analytics.tsx` fetches data from the database and performs calculations. It's essential to ensure that this function is optimized for performance and doesn't cause any bottlenecks. * The `STALE_THRESHOLD_DAYS` constant is defined as a magic number. It's better to define it as a configurable constant or an environment variable. * The `cutoffDate` calculation in the `loader` function uses the `Date` object, which might not be suitable for all time zones. Consider using a library like `moment` or `date-fns` for date calculations. * The `normalized` array is created using the `map` method, which can be slow for large datasets. Consider using a more efficient data processing method, such as `for...of` or `reduce`. * The `staleItems` array is filtered using the `filter` method, which can also be slow for large datasets. Consider using a more efficient filtering method, such as `for...of` or `reduce`. * The `totalInventoryCost`, `totalEstimatedMarketValue`, and `itemsMissingMarketData` variables are calculated using `for...of` loops. Consider using `reduce` or `forEach` for better performance. * The `projectedProfit` and `projectedMarginPct` calculations are performed using simple arithmetic operations. Consider adding input validation and error handling to ensure that these calculations are accurate and reliable. * The `AnalyticsPage` component uses the `useLoaderData` hook to fetch data from the `loader` function. Consider adding error handling and loading indicators to improve the user experience. * The `ProfitForecast` and `StaleInventoryCard` components are not wrapped in a `React.memo` or `React.PureComponent` to prevent unnecessary re-renders. Consider adding memoization to improve performance. * The `app-sidebar.tsx` file uses the `document.documentElement` object to toggle the theme. Consider using a more robust theme management solution, such as a context API or a state management library. * The `app-sidebar.tsx` file uses the `localStorage` API to store the theme preference. Consider using a more secure storage solution, such as a cookie or a token-based authentication system.💡 Suggestions & Best Practices* Consider adding input validation and error handling to the `loader` function to ensure that the data is accurate and reliable. * Use a more efficient data processing method, such as `for...of` or `reduce`, to create the `normalized` array. * Use a more efficient filtering method, such as `for...of` or `reduce`, to create the `staleItems` array. * Consider using a library like `moment` or `date-fns` for date calculations to ensure that the `cutoffDate` calculation is accurate and reliable. * Consider adding memoization to the `ProfitForecast` and `StaleInventoryCard` components to prevent unnecessary re-renders. * Consider using a more robust theme management solution, such as a context API or a state management library, to manage the theme preference. * Consider using a more secure storage solution, such as a cookie or a token-based authentication system, to store the theme preference. * Consider adding loading indicators and error handling to the `AnalyticsPage` component to improve the user experience. * Consider using a more efficient calculation method, such as `reduce` or `forEach`, to calculate the `totalInventoryCost`, `totalEstimatedMarketValue`, and `itemsMissingMarketData` variables. * Consider adding input validation and error handling to the `projectedProfit` and `projectedMarginPct` calculations to ensure that they are accurate and reliable. |
|
Hi @rushikesh-bobade , Thanks so much for the review and the kind words! 🙌 Just wanted to clarify on the sidebar link — it looks like it was already added in this PR (line in { to: "/app/analytics", label: "Analytics", icon: <IconTrendingUp size={20} /> },It's placed right after the "AI Insights" entry and points to the new That said, to match your suggested wording exactly, I've updated the label from |
|
You are 100% correct, and I owe you a massive apology! I completely missed that line when I was reviewing the raw diff, and incorrectly blamed the AI bot for hallucinating. You had it perfectly right the very first time! 😅 Thank you so much for being so gracious about my mistake, and for pushing that follow-up commit to update the label text anyway. It looks fantastic. You wrote an incredibly high-quality feature here—the Prisma queries are efficient, the UI is perfectly matched to our design system, and your logic is rock solid. Approving and merging right now. Amazing job! |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
🎉 Congratulations @shivi14112007-create! 🎉 Your Pull Request has been successfully merged! Thank you so much for your hard work and contribution to FlipTrack. We really appreciate it! 🚀 |
Description
Adds an "Analytics & Insights" dashboard tab that surfaces two things advanced users asked for: stale inventory (items sitting in
IN_STOCKstatus for more than 60 days) and a basic profit forecast comparing current inventory purchase cost vs. estimated market value./app/analytics, added to the sidebar next to "AI Insights."InventoryItem(statusIN_STOCK), joins each item's most recentMarketPricesnapshot (lastSold, falling back toaskPrice) to estimate current value, and flags items older than 60 days as stale.MarketPricesnapshot yet, the forecast falls back to that item'saskingPriceorpurchasePriceinstead of skewing the numbers to zero — surfaced to the user via a small disclaimer banner so it's not silently misleading.StaleInventoryCardandProfitForecastcomponents live inapp/blocks/analytics/, styled using the existing design tokens fromtheme.cssto match the rest of the app (light/dark both supported automatically via CSS variables).Related Issues
Closes #126
Type of Change
Checklist:
Screenshots
Notes for reviewer
StaleInventoryCard.tsx/ProfitForecast.tsxin PascalCase; I kept that exact naming since it's what was requested, though every other folder underapp/blocks/uses kebab-case file names. Happy to rename for consistency if preferred.STALE_THRESHOLD_DAYSis a constant at the top ofanalytics.tsxif the 60-day window needs to be tuned later.