Skip to content

Conversation

@Boxuan-Matty-Lin
Copy link
Owner

This pull request introduces a major refactor and redesign of the Kopi Maker tab, focusing on improved UI, state management, and codebase cleanup. It removes unused components and modal functionality, introduces new UI components for kopi customization, and updates the documentation and dependencies to reflect these changes.

Kopi Maker UI and State Redesign:

  • The Kopi tab (app/(tabs)/kopi.tsx) is rebuilt with a two-section layout: a preview area and interactive option selectors for milk, sugar, strength, and temperature, powered by a Zustand store. A custom SVG curve visually separates sections, and a "Brew" button is added. ([app/(tabs)/kopi.tsxL1-R111](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-f78a2a8d52ae26b5d252e01225fa3864692bb07f55d4ecf0c1cd789224736e29L1-R111))
  • New reusable components are introduced: KopiCupPreview for displaying the selected kopi name, and OptionSelector for user selection of kopi options. ([[1]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-11fffcf876611b227a744028ffcea9b497fb5c854c43d6139cc60ce5849b6f9aR1-R26), [[2]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-0c7d038ed3a4687ae63226f3770c9cddde5081f89de7ed6438f2f9224c8cad69R1-R50), [[3]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-c78dee33b05b07063fc2e0dafd39a752a11f0a430d3ac29331075059afb9b2a7R1-R2))
  • New color tokens and theme values are added for the updated UI, both in the theme constants and global CSS. ([[1]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-e266bec56ac932c8c0a110dbe572b7552bf0ca146d5033572074018d1b61033aR17-R20), [[2]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-c3a392bca08e12a4456b4e08e3900540c977d5f83fe9da4925b0538e354342fcR12-R14))

Codebase Cleanup and Removal of Unused Components:

  • Removes the modal feature and its registration from the app, as well as unused or template components (hello-wave, parallax-scroll-view, external-link, and themed text/view). ([[1]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-2e642ecf25da57eeaadd6bbed731ce44ff428a12b9448aac88a196a0d840de4fL1-L29), [[2]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-a297596ca5a79abd3db7509592a07106f1c27c02ee55895a4dee8bcce9f7da57L19), [[3]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-bb410e30d8c9af736088170f7e2dd151f91fae55e890550b446039fd5aa5403bL1-L19), [[4]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-6f16362f0746e762c9f020d6b9a495af5adeb4b080fd05d807e426399786a053L1-L79), [[5]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-0d36e81c07fa81fd53e0226d4e9fab2e5eeae508ad1f0f30a150bdad4a8791c3L1-L25))

Documentation and Tooling Updates:

  • Updates AGENTS.md to document the new UI architecture, state management, and styling approach, replacing the previous technical summary. ([[1]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-a54ff182c7e8acf56acfd6e4b9c3ff41e2c41a31c9b211b2deb9df75d9a478f9R1-R28), [[2]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-4244d88adfe5757005318fe9a46f631ada97796532af355e25fe504c2bc6df57L1-L28))
  • Adds react-native-svg as a new dependency for custom SVG rendering in the UI, updating both package.json and lockfile. ([[1]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-7ae45ad102eab3b6d7e7896acd08c427a9b25b346470d7bc6507b6481575d519R38), [[2]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-32824c984905bb02bc7ffcef96a77addd1f1602cff71a11fbbfdd7f53ee026bbL61-R61), [[3]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-32824c984905bb02bc7ffcef96a77addd1f1602cff71a11fbbfdd7f53ee026bbR83-R85))
  • Lockfile (pnpm-lock.yaml) updated for new and removed dependencies. ([[1]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-32824c984905bb02bc7ffcef96a77addd1f1602cff71a11fbbfdd7f53ee026bbL61-R61), [[2]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-32824c984905bb02bc7ffcef96a77addd1f1602cff71a11fbbfdd7f53ee026bbR83-R85), [[3]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-32824c984905bb02bc7ffcef96a77addd1f1602cff71a11fbbfdd7f53ee026bbR1696-R1698), [[4]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-32824c984905bb02bc7ffcef96a77addd1f1602cff71a11fbbfdd7f53ee026bbR1896-R1906), [[5]](https://github.com/Boxuan-Matty-Lin/kopi-shop/pull/7/files#diff-32824c984905bb02bc7ffcef96a77addd1f1602cff71a11fbbfdd7f53ee026bbR2012-R2024))

These changes modernize the Kopi tab, streamline the codebase, and set up a more maintainable and extensible foundation for future development.

@Boxuan-Matty-Lin Boxuan-Matty-Lin self-assigned this Nov 23, 2025
@Boxuan-Matty-Lin Boxuan-Matty-Lin added documentation Improvements or additions to documentation enhancement New feature or request labels Nov 23, 2025
@Boxuan-Matty-Lin Boxuan-Matty-Lin linked an issue Nov 23, 2025 that may be closed by this pull request
@Boxuan-Matty-Lin
Copy link
Owner Author

image

@Boxuan-Matty-Lin Boxuan-Matty-Lin merged commit 1f84a69 into main Nov 23, 2025
5 checks passed
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a complete redesign of the Kopi Maker tab, transforming it from a placeholder into a fully functional kopi customization interface. The implementation introduces a Zustand-based state management system, new reusable UI components, and a visually distinctive two-section layout with a custom SVG curve separator. The PR also includes necessary cleanup by removing unused template components and updating documentation.

Key Changes:

  • Implemented interactive kopi customization UI with state management (Zustand store, utility functions, type definitions)
  • Created reusable components (KopiCupPreview, OptionSelector) with NativeWind styling
  • Added new color tokens (cream, warm-beige, accent) across theme system
  • Removed unused template components (modal, parallax-scroll-view, external-link, hello-wave)

Reviewed changes

Copilot reviewed 17 out of 19 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
app/(tabs)/kopi.tsx Main screen redesign with preview section, option selectors, SVG curve divider, and brew button
stores/kopiMakerStore.ts Zustand store managing kopi selection state (milkiness, sweetness, strength, temperature) with derived helpers
utils/kopiInfer.ts Utility functions mapping kopi selections to display names and order phrases
types/kopi.ts Type definitions for kopi options, selections, and UI option items
components/kopi/KopiCupPreview.tsx Preview component displaying selected kopi name with curved bottom border
components/kopi/OptionSelector.tsx Reusable option selector component with Pressable buttons
components/kopi/index.ts Component exports barrel file
constants/theme.ts Added cream, warmBeige, and accent colors to palette
global.css Added CSS variables for new colors
tailwind.config.js Extended Tailwind color configuration
package.json Added react-native-svg dependency
pnpm-lock.yaml Lockfile updates for new dependencies
AGENTS.md Updated documentation with current architecture
app/modal.tsx Removed unused modal component
app/_layout.tsx Removed modal route registration
components/parallax-scroll-view.tsx Removed unused template component
components/hello-wave.tsx Removed unused template component
components/external-link.tsx Removed unused template component
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// 关键:往下压 CURVE_DEPTH,让“曲线边”贴在分界处
bottom: -CURVE_DEPTH,
zIndex: 999,
elevation: 999, // 安卓需要
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This inline comment is in Chinese. Code comments should be in English for consistency and accessibility.

Suggestion: Replace with an English comment like:

elevation: 999, // Needed for Android
Suggested change
elevation: 999, // 安卓需要
elevation: 999, // Needed for Android

Copilot uses AI. Check for mistakes.
Comment on lines +11 to 19
import { Dimensions, Pressable, ScrollView, Text, View } from "react-native";
import Svg, { Path } from "react-native-svg";

const { width } = Dimensions.get("window");
const CURVE_HEIGHT = 80;
const CURVE_DEPTH = 50;
const SVG_H = CURVE_HEIGHT + CURVE_DEPTH;

export default function KopiScreen() {
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling Dimensions.get("window") at module level can cause issues during initial render and doesn't respond to dimension changes (e.g., device rotation, window resize on web).

Recommendation: Move this inside the component and use useState with an effect to handle dimension changes, or use useWindowDimensions() hook from React Native:

import { useWindowDimensions } from 'react-native';

export default function KopiScreen() {
  const { width } = useWindowDimensions();
  // ... rest of code
Suggested change
import { Dimensions, Pressable, ScrollView, Text, View } from "react-native";
import Svg, { Path } from "react-native-svg";
const { width } = Dimensions.get("window");
const CURVE_HEIGHT = 80;
const CURVE_DEPTH = 50;
const SVG_H = CURVE_HEIGHT + CURVE_DEPTH;
export default function KopiScreen() {
import { Pressable, ScrollView, Text, View, useWindowDimensions } from "react-native";
import Svg, { Path } from "react-native-svg";
const CURVE_HEIGHT = 80;
const CURVE_DEPTH = 50;
const SVG_H = CURVE_HEIGHT + CURVE_DEPTH;
export default function KopiScreen() {
const { width } = useWindowDimensions();

Copilot uses AI. Check for mistakes.
Comment on lines +2 to +11
import { Dimensions, Text, View } from 'react-native';

interface KopiCupPreviewProps {
name: string;
}

const { width } = Dimensions.get('window');
const curveRadius = width; // big radius to form a smooth smile at the bottom edge

export const KopiCupPreview = ({ name }: KopiCupPreviewProps) => {
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the main Kopi screen, calling Dimensions.get("window") at module level doesn't respond to dimension changes and can cause layout issues during rotation or window resize.

Recommendation: Use useWindowDimensions() hook inside the component:

import { useWindowDimensions, Text, View } from 'react-native';

export const KopiCupPreview = ({ name }: KopiCupPreviewProps) => {
  const { width } = useWindowDimensions();
  const curveRadius = width;
  // ... rest of code
Suggested change
import { Dimensions, Text, View } from 'react-native';
interface KopiCupPreviewProps {
name: string;
}
const { width } = Dimensions.get('window');
const curveRadius = width; // big radius to form a smooth smile at the bottom edge
export const KopiCupPreview = ({ name }: KopiCupPreviewProps) => {
import { useWindowDimensions, Text, View } from 'react-native';
interface KopiCupPreviewProps {
name: string;
}
export const KopiCupPreview = ({ name }: KopiCupPreviewProps) => {
const { width } = useWindowDimensions();
const curveRadius = width; // big radius to form a smooth smile at the bottom edge

Copilot uses AI. Check for mistakes.
<View className="absolute bottom-8 left-0 right-0 px-6">
<Pressable
className="bg-dark-coffee py-4 rounded-2xl items-center shadow-lg active:opacity-90"
onPress={() => console.log("Brewing:", phrase)}
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Brew" button lacks accessibility properties, which makes it less accessible to users with screen readers.

Recommendation: Add accessibilityLabel and accessibilityRole:

<Pressable
  className="bg-dark-coffee py-4 rounded-2xl items-center shadow-lg active:opacity-90"
  onPress={() => console.log("Brewing:", phrase)}
  accessibilityLabel={`Brew ${phrase}`}
  accessibilityRole="button"
>
Suggested change
onPress={() => console.log("Brewing:", phrase)}
onPress={() => console.log("Brewing:", phrase)}
accessibilityLabel={`Brew ${phrase}`}
accessibilityRole="button"

Copilot uses AI. Check for mistakes.

## State & Domain
- Zustand store `stores/kopiMakerStore.ts`: holds kopi selection (`milkiness`, `sweetness`, `strength`, `temperature`), setters/reset, derived `baseName/displayName/phrase` via `utils/kopiInfer`.
- Domain types `types/kopi.ts`: option groups, option lists, `KopiSelection`, default selection. Temperature replaces earlier “state” naming.
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence is unclear: "Temperature replaces earlier 'state' naming." This seems to reference previous code state that reviewers cannot see, making the documentation confusing for someone new to the codebase.

Recommendation: Either clarify what this means or remove this historical reference:

- Domain types `types/kopi.ts`: option groups, option lists, `KopiSelection`, default selection.
Suggested change
- Domain types `types/kopi.ts`: option groups, option lists, `KopiSelection`, default selection. Temperature replaces earlier “state” naming.
- Domain types `types/kopi.ts`: option groups, option lists, `KopiSelection`, default selection.

Copilot uses AI. Check for mistakes.
Comment on lines +77 to +88
/**
* Hook to access Kopi Maker store.
*
* State:
* - milkiness, sweetness, strength, temperature
*
* Actions:
* - setMilkiness, setSweetness, setStrength, setTemperature, reset
*
* Derived helpers:
* - baseName, displayName, phrase
*/
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The JSDoc comment block has inconsistent formatting. Lines 81 and 84 have misaligned asterisks that don't align with the rest of the comment block structure.

Suggestion: Align all asterisks consistently:

 /**
  * Hook to access Kopi Maker store.
  *
  * State:
  * - milkiness, sweetness, strength, temperature
  *
  * Actions:
  * - setMilkiness, setSweetness, setStrength, setTemperature, reset
  *
  * Derived helpers:
  * - baseName, displayName, phrase
  */

Copilot uses AI. Check for mistakes.
<View className="absolute bottom-8 left-0 right-0 px-6">
<Pressable
className="bg-dark-coffee py-4 rounded-2xl items-center shadow-lg active:opacity-90"
onPress={() => console.log("Brewing:", phrase)}
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a console.log statement in the production code. While this might be a placeholder for future functionality, console logs should generally be removed from production code or replaced with proper logging/handling.

Recommendation: Either implement the actual brew functionality or remove the console log and add a TODO comment:

onPress={() => {
  // TODO: Implement brew functionality
}}
Suggested change
onPress={() => console.log("Brewing:", phrase)}
onPress={() => {
// TODO: Implement brew functionality
}}

Copilot uses AI. Check for mistakes.
hint?: string; // optional, local term or explanation, e.g., "(Gao)"
};

/* 6) Four groups of UI options (directly used for Picker map rendering) */
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment starts with "6)" but there's no numbered list context (no items 1-5 visible). This suggests either:

  1. Previous numbered items were removed, or
  2. This is a copy-paste artifact

Recommendation: Remove the number prefix:

/* Four groups of UI options (used for rendering option selectors) */
Suggested change
/* 6) Four groups of UI options (directly used for Picker map rendering) */
/* Four groups of UI options (directly used for Picker map rendering) */

Copilot uses AI. Check for mistakes.
<View style={{ flex: 0.4, zIndex: 2, backgroundColor: topBg }}>
<KopiCupPreview name={phrase} />

{/* 微笑曲线分界 */}
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is in Chinese. Code comments should be in English for consistency and accessibility.

Suggestion: Replace with an English comment like:

{/* Smile curve divider */}
Suggested change
{/* 微笑曲线分界 */}
{/* Smile curve divider */}

Copilot uses AI. Check for mistakes.
position: "absolute",
left: 0,
right: 0,
// 关键:往下压 CURVE_DEPTH,让“曲线边”贴在分界处
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This inline comment is in Chinese. Code comments should be in English for consistency and accessibility.

Suggestion: Replace with an English comment like:

// Key: Push down by CURVE_DEPTH so the "curve edge" aligns at the boundary
Suggested change
// 关键:往下压 CURVE_DEPTH,让“曲线边”贴在分界处
// Key: Push down by CURVE_DEPTH so the "curve edge" aligns at the boundary

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MVP 0.1.3 – Kopi Maker screen

2 participants