Initial commit

This commit is contained in:
2026-06-29 14:06:12 +02:00
commit c2c3270c66
37 changed files with 10524 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
{
"dependencies": {
"i18next": "latest",
"react-i18next": "latest"
},
"expoDependencies": ["expo-localization"],
"appJson": {
"expo": {
"plugins": ["expo-localization"]
}
}
}
+1
View File
@@ -0,0 +1 @@
import './lang/translation';
@@ -0,0 +1,13 @@
import { Resource } from 'i18next';
export const fallbackChecker = (resources: Resource, fallbackLng: string) => {
const languages = Object.keys(resources);
const hasFallback = languages.find((key) => fallbackLng === key);
if (!hasFallback) {
throw new Error(
`fallbackLng "${fallbackLng}", is not present in your resources, please check your config, languages available: ${languages.join(', ')}`
);
}
return fallbackLng;
};
+25
View File
@@ -0,0 +1,25 @@
/* eslint-disable import/no-named-as-default-member */
import i18n, { Resource } from 'i18next';
import { initReactI18next } from 'react-i18next';
import { fallbackChecker } from './fallbackChecker';
import { languageDetector } from './languageDetector';
type Init18n = {
resources: Resource;
fallbackLng: string;
};
export const init18n = ({ resources, fallbackLng }: Init18n) => {
return i18n
.use(languageDetector)
.use(initReactI18next)
.init({
resources,
fallbackLng: fallbackChecker(resources, fallbackLng),
compatibilityJSON: 'v3', // By default React Native projects does not support Intl
interpolation: {
escapeValue: false,
},
});
};
@@ -0,0 +1,13 @@
import * as Localization from 'expo-localization';
import { LanguageDetectorModule } from 'i18next';
export const languageDetector: LanguageDetectorModule = {
type: 'languageDetector',
detect: () => {
const locales = Localization.getLocales();
const firstLanguageCode = locales[0].languageCode ?? 'nl';
return firstLanguageCode;
},
init: () => {},
cacheUserLanguage: () => {},
};
@@ -0,0 +1,16 @@
import { init18n } from 'lang/i18n/init';
import nl from './nl';
export const resources = {
nl: {
translation: nl,
},
};
export const fallbackLng = 'nl';
export type LanguageCode = keyof typeof resources;
const i18n = init18n({ resources, fallbackLng });
export default i18n;
@@ -0,0 +1 @@
{}
@@ -0,0 +1,5 @@
import general from './general.json';
export default {
general,
};
+6
View File
@@ -0,0 +1,6 @@
module.exports = function (api) {
api.cache(true);
return {
presets: [['babel-preset-expo', { jsxImportSource: 'nativewind' }], 'nativewind/babel'],
};
};
+3
View File
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
+6
View File
@@ -0,0 +1,6 @@
const { getDefaultConfig } = require('expo/metro-config');
const { withNativeWind } = require('nativewind/metro');
const config = getDefaultConfig(__dirname);
module.exports = withNativeWind(config, { input: './global.css' });
+1
View File
@@ -0,0 +1 @@
/// <reference types="nativewind/types" />
+12
View File
@@ -0,0 +1,12 @@
{
"dependencies": {
"nativewind": "latest",
"react-native-reanimated": "latest",
"react-native-safe-area-context": "latest"
},
"devDependencies": {
"tailwindcss": "^3.4.17",
"prettier-plugin-tailwindcss": "^0.5.11",
"babel-preset-expo": "latest"
}
}
+1
View File
@@ -0,0 +1 @@
import '../global.css';
@@ -0,0 +1,11 @@
import { StatusBar } from 'expo-status-bar';
import { Text, View } from 'react-native';
export default function DefaultScreen() {
return (
<View className="flex-1 bg-white items-center justify-center">
<Text>Open up /src/screens/DefaultScreen.tsx to start working on your app!</Text>
<StatusBar style="auto" />
</View>
);
}
+10
View File
@@ -0,0 +1,10 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
// NOTE: Update this to include the paths to all files that contain Nativewind classes.
content: ['./src/**/*.{js,jsx,ts,tsx}'],
presets: [require('nativewind/preset')],
theme: {
extend: {},
},
plugins: [],
};
+12
View File
@@ -0,0 +1,12 @@
{
"dependencies": {
"@react-navigation/native": "latest",
"@react-navigation/stack": "latest"
},
"expoDependencies": [
"react-native-screens",
"react-native-safe-area-context",
"react-native-gesture-handler",
"@react-native-masked-view/masked-view"
]
}
+9
View File
@@ -0,0 +1,9 @@
import RootNavigator from './navigation/RootNavigator';
function App() {
return <RootNavigator />;
}
export default function Wrapper() {
return <App />;
}
@@ -0,0 +1,16 @@
import { createStackNavigator } from '@react-navigation/stack';
import DefaultScreen from '../screens/DefaultScreen';
const Stack = createStackNavigator<RootParamList>();
export default function RootNavigator() {
return (
<Stack.Navigator initialRouteName="default">
<Stack.Screen name="default" component={DefaultScreen} />
</Stack.Navigator>
);
}
export type RootParamList = {
default: undefined;
};
@@ -0,0 +1,20 @@
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
export default function DefaultScreen() {
return (
<View style={styles.container}>
<Text>Open up /src/screens/DefaultScreen.tsx to start working on your app!</Text>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});