Skip to content
This repository was archived by the owner on Aug 24, 2026. It is now read-only.
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
6 changes: 6 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# We put the id's of the commits that we want to ignore in this file, one per line.
# For example: this is a format commit that we don't want to see in the blame output:
2d222c86c982bef96b232e705dd536f4a7cd853b
# Because it doesn't change the code, just the formatting:
# Tell git to use this file for blame by running the following command in your terminal:
# git config blame.ignoreRevsFile .git-blame-ignore-revs
21 changes: 21 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Checks

on:
workflow_dispatch:
pull_request:
push:
branches:
- main

jobs:
checks:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install dependencies (root)
run: npm install

- name: Run checks (root script)
run: npm run checks
22 changes: 11 additions & 11 deletions App.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
// FILE: App.tsx
import { ThemeProvider } from "@/core/theme/ThemeContext";
import React, { useEffect } from "react";
import { StatusBar } from "expo-status-bar";
import useAppStore from "@/core/store/appStore";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import i18n from "@/core/i18n";
import { useForceUpdate } from "@/core/hooks/useForceUpdate";
import { I18nManager } from "react-native";
import { NavigationContainer } from "@react-navigation/native";
import AppNavigator from "@/navigation/AppNavigator";
import { ThemeProvider } from '@/core/theme/ThemeContext';
import React, { useEffect } from 'react';
import { StatusBar } from 'expo-status-bar';
import useAppStore from '@/core/store/appStore';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import i18n from '@/core/i18n';
import { useForceUpdate } from '@/core/hooks/useForceUpdate';
import { I18nManager } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import AppNavigator from '@/navigation/AppNavigator';

I18nManager.allowRTL(true);

Expand All @@ -33,7 +33,7 @@ export default function App() {
<GestureHandlerRootView style={{ flex: 1 }}>
<NavigationContainer>
<AppContent />
<StatusBar style={"auto"} />
<StatusBar style={'auto'} />
</NavigationContainer>
</GestureHandlerRootView>
</ThemeProvider>
Expand Down
10 changes: 5 additions & 5 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
const { defineConfig } = require("eslint/config");
const expoConfig = require("eslint-config-expo/flat");
const eslintPluginPrettierRecommended = require("eslint-plugin-prettier/recommended");
const { defineConfig } = require('eslint/config');
const expoConfig = require('eslint-config-expo/flat');
const eslintPluginPrettierRecommended = require('eslint-plugin-prettier/recommended');

module.exports = defineConfig([
expoConfig,
eslintPluginPrettierRecommended,
{
rules: {
"prettier/prettier": "warn",
'prettier/prettier': 'warn',
},
ignores: ["dist/*", "node_modules/*", "/.expo"],
ignores: ['dist/*', 'node_modules/*', '/.expo'],
},
]);
4 changes: 2 additions & 2 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { registerRootComponent } from "expo";
import { registerRootComponent } from 'expo';

import App from "./App";
import App from './App';

// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
// It also ensures that whether you load the app in Expo Go or in a native build,
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
"format": "prettier --write .",
"checks:lint": "expo lint --fix",
"checks:tsc": "tsc --noEmit",
"checks:export": "expo export",
"checks:format": "prettier --check .",
"checks": "npm run checks:lint && npm run checks:tsc && npm run checks:format",
"checks": "npm run checks:lint && npm run checks:tsc && npm run checks:export && npm run checks:format",
"lint": "expo lint"
},
"dependencies": {
Expand Down
31 changes: 11 additions & 20 deletions src/components/FAB.tsx
Original file line number Diff line number Diff line change
@@ -1,43 +1,34 @@
// src/components/FAB.tsx
import { AppTheme } from "@/constants/theme";
import { useTheme } from "@/core/theme/ThemeContext";
import { MaterialCommunityIcons } from "@expo/vector-icons";
import React from "react";
import {
I18nManager,
StyleSheet,
TouchableOpacity,
TouchableOpacityProps,
} from "react-native";
import { AppTheme } from '@/constants/theme';
import { useTheme } from '@/core/theme/ThemeContext';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import React from 'react';
import { I18nManager, StyleSheet, TouchableOpacity, TouchableOpacityProps } from 'react-native';

export const FAB = (props: TouchableOpacityProps) => {
const { theme } = useTheme();
const styles = getStyles(theme);

return (
<TouchableOpacity style={styles.container} activeOpacity={0.7} {...props}>
<MaterialCommunityIcons
name="plus"
size={32}
color={theme.colors.primaryContrast}
/>
<MaterialCommunityIcons name="plus" size={32} color={theme.colors.primaryContrast} />
</TouchableOpacity>
);
};

const getStyles = (theme: AppTheme) =>
StyleSheet.create({
container: {
position: "absolute",
position: 'absolute',
bottom: theme.spacing.l,
[I18nManager.isRTL ? "left" : "right"]: theme.spacing.l,
[I18nManager.isRTL ? 'left' : 'right']: theme.spacing.l,
width: 60,
height: 60,
borderRadius: 16,
backgroundColor: theme.colors.primary,
justifyContent: "center",
alignItems: "center",
shadowColor: "#000",
justifyContent: 'center',
alignItems: 'center',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
Expand Down
36 changes: 16 additions & 20 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// src/components/Header.tsx
import { AppTheme } from "@/constants/theme";
import { useTheme } from "@/core/theme/ThemeContext";
import React from "react";
import { StyleSheet } from "react-native";
import { EdgeInsets } from "react-native-safe-area-context";
import { Box } from "./base/Box";
import { ThemedText } from "./base/ThemedText";
import { AppTheme } from '@/constants/theme';
import { useTheme } from '@/core/theme/ThemeContext';
import React from 'react';
import { StyleSheet } from 'react-native';
import { EdgeInsets } from 'react-native-safe-area-context';
import { Box } from './base/Box';
import { ThemedText } from './base/ThemedText';

export type HeaderProps = {
title: string;
Expand All @@ -27,9 +27,7 @@ export const Header = ({

return (
<Box style={styles.container}>
<Box style={styles.actionSlot}>
{renderLeftAction && renderLeftAction()}
</Box>
<Box style={styles.actionSlot}>{renderLeftAction && renderLeftAction()}</Box>

<Box style={styles.titleContainer}>
<ThemedText style={styles.title} numberOfLines={1}>
Expand All @@ -42,33 +40,31 @@ export const Header = ({
)}
</Box>

<Box style={styles.actionSlot}>
{renderRightAction && renderRightAction()}
</Box>
<Box style={styles.actionSlot}>{renderRightAction && renderRightAction()}</Box>
</Box>
);
};

const getStyles = (theme: AppTheme, insets: EdgeInsets) =>
StyleSheet.create({
container: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: theme.spacing.m,
height: 60 + insets.top,
paddingTop: insets.top,
backgroundColor: theme.colors.foreground,
},
actionSlot: {
width: 40,
justifyContent: "center",
alignItems: "center",
justifyContent: 'center',
alignItems: 'center',
},
titleContainer: {
flex: 1,
justifyContent: "center",
alignItems: "center",
justifyContent: 'center',
alignItems: 'center',
},
title: {
fontSize: theme.typography.fontSize.l,
Expand Down
16 changes: 8 additions & 8 deletions src/components/Screen.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// src/components/Screen.tsx
import { AppTheme } from "@/constants/theme";
import { useTheme } from "@/core/theme/ThemeContext";
import React from "react";
import { StyleSheet } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { Box } from "./base/Box";
import { Header, HeaderProps } from "./Header";
import { AppTheme } from '@/constants/theme';
import { useTheme } from '@/core/theme/ThemeContext';
import React from 'react';
import { StyleSheet } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { Box } from './base/Box';
import { Header, HeaderProps } from './Header';

type ScreenProps = Partial<Omit<HeaderProps, "insets">> & {
type ScreenProps = Partial<Omit<HeaderProps, 'insets'>> & {
children: React.ReactNode;
};

Expand Down
4 changes: 2 additions & 2 deletions src/components/base/Box.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// src/components/base/Box.tsx
import { View, ViewProps } from "react-native";
import React from "react";
import { View, ViewProps } from 'react-native';
import React from 'react';

// For now, it's a simple pass-through.
// It establishes a pattern for a component that will become more powerful.
Expand Down
6 changes: 3 additions & 3 deletions src/components/base/ThemedText.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// src/components/base/ThemedText.tsx
import { useTheme } from "@/core/theme/ThemeContext";
import React from "react";
import { Text, TextProps } from "react-native";
import { useTheme } from '@/core/theme/ThemeContext';
import React from 'react';
import { Text, TextProps } from 'react-native';

export const ThemedText = (props: TextProps) => {
const { theme } = useTheme();
Expand Down
8 changes: 4 additions & 4 deletions src/components/base/ThemedTextInput.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// src/components/base/ThemedTextInput.tsx
import { AppTheme } from "@/constants/theme";
import { useTheme } from "@/core/theme/ThemeContext";
import React from "react";
import { StyleSheet, TextInput, TextInputProps } from "react-native";
import { AppTheme } from '@/constants/theme';
import { useTheme } from '@/core/theme/ThemeContext';
import React from 'react';
import { StyleSheet, TextInput, TextInputProps } from 'react-native';

export const ThemedTextInput = (props: TextInputProps) => {
const { theme } = useTheme();
Expand Down
36 changes: 18 additions & 18 deletions src/constants/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,28 @@

const palette = {
// Grays
neutral100: "#FFFFFF",
neutral200: "#F4F2F1",
neutral300: "#D7CEC9",
neutral400: "#B6ACA6",
neutral500: "#978F8A",
neutral600: "#564F4A",
neutral700: "#3C3835",
neutral800: "#2B2724",
neutral900: "#1C1917",
neutral100: '#FFFFFF',
neutral200: '#F4F2F1',
neutral300: '#D7CEC9',
neutral400: '#B6ACA6',
neutral500: '#978F8A',
neutral600: '#564F4A',
neutral700: '#3C3835',
neutral800: '#2B2724',
neutral900: '#1C1917',

// Primary (Example: A muted green)
primary100: "#E3F9E5",
primary200: "#C1EAC5",
primary300: "#A3D9A5",
primary400: "#85C78A",
primary500: "#67B56F",
primary600: "#4F8B55",
primary100: '#E3F9E5',
primary200: '#C1EAC5',
primary300: '#A3D9A5',
primary400: '#85C78A',
primary500: '#67B56F',
primary600: '#4F8B55',

// Accents for statuses
accentRed: "#D9534F",
accentYellow: "#F0AD4E",
accentGreen: "#5CB85C",
accentRed: '#D9534F',
accentYellow: '#F0AD4E',
accentGreen: '#5CB85C',
} as const;

export const colors = {
Expand Down
Loading