This commit is contained in:
Philip Cesar Garay
2025-07-31 21:25:33 +08:00
parent 5cfbc81e3a
commit 84fc719a10
307 changed files with 46470 additions and 0 deletions
+80
View File
@@ -0,0 +1,80 @@
import React, { useGlobal } from "reactn";
import { StyleSheet } from "react-native";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { Motion } from "@legendapp/motion";
import { responsiveHeight } from "../actions/responsiveSizes.js";
import useLayoutType from "../hooks/useLayoutType.js";
import { Routes } from "./Routes";
import { Palette } from "../styles";
import { tabs } from "../assets";
import TabBar from "./TabBar";
import HomeStack from "./HomeStack";
import ChatStack from "./ChatStack";
import SettingsStack from "./SettingsStack";
const bottomTabStyles = StyleSheet.create({
icon: {
width: responsiveHeight(5),
height: responsiveHeight(5),
resizeMode: "contain",
},
});
const BottomTab = createBottomTabNavigator();
export const BottomTabScreen = () => {
const renderIcon = (icon, focused) => (
<Motion.Image
resizeMode={"contain"}
animate={{
tintColor: focused ? Palette.primary : Palette.white,
}}
style={[
bottomTabStyles.icon,
{
width: "55%",
height: "55%",
},
]}
source={icon}
/>
);
return (
<BottomTab.Navigator tabBar={(props) => <TabBar {...props} />}>
<BottomTab.Screen
name={Routes.HomeStack}
component={HomeStack}
options={{
headerShown: false,
tabBarShowLabel: true,
tabBarIcon: ({ focused }) => renderIcon(tabs.home, focused),
}}
/>
<BottomTab.Screen
name={Routes.ChatStack}
component={ChatStack}
options={{
headerShown: false,
tabBarShowLabel: true,
tabBarIcon: ({ focused }) => renderIcon(tabs.chat, focused),
}}
/>
<BottomTab.Screen
name={Routes.SettingsStack}
component={SettingsStack}
options={{
headerShown: false,
tabBarShowLabel: true,
tabBarIcon: ({ focused }) => renderIcon(tabs.settings, focused),
}}
/>
</BottomTab.Navigator>
);
};
+41
View File
@@ -0,0 +1,41 @@
import React from "react";
import { createStackNavigator } from "@react-navigation/stack";
import { Palette } from "../styles";
import { Routes } from "./Routes";
import Chat from "../screens/Chat";
const screenOptions = {
headerShown: false,
cardOverlayEnabled: true,
headerStyle: {
backgroundColor: Palette.background,
},
headerTitleAlign: "center",
headerBackTitleVisible: false,
};
const HomeStack = createStackNavigator();
export default () => {
return (
<HomeStack.Navigator
initialRouteName={Routes.Settings}
screenOptions={[
{
contentStyle: {
backgroundColor: Palette.white,
},
},
screenOptions,
]}
>
<HomeStack.Screen
name={Routes.Chat}
component={Chat}
options={{ headerShown: false }}
/>
</HomeStack.Navigator>
);
};
+41
View File
@@ -0,0 +1,41 @@
import React from "react";
import { createStackNavigator } from "@react-navigation/stack";
import { Palette } from "../styles";
import { Routes } from "./Routes";
import Home from "../screens/Home";
const screenOptions = {
headerShown: false,
cardOverlayEnabled: true,
headerStyle: {
backgroundColor: Palette.background,
},
headerTitleAlign: "center",
headerBackTitleVisible: false,
};
const HomeStack = createStackNavigator();
export default function HomeStackScreen() {
return (
<HomeStack.Navigator
initialRouteName={Routes.Home}
screenOptions={[
{
contentStyle: {
backgroundColor: Palette.white,
},
},
screenOptions,
]}
>
<HomeStack.Screen
name={Routes.Home}
component={Home}
options={{ headerShown: false }}
/>
</HomeStack.Navigator>
);
}
+97
View File
@@ -0,0 +1,97 @@
import React from "react";
import { createStackNavigator } from "@react-navigation/stack";
import { Palette } from "../styles";
import { Routes } from "./Routes";
import { BottomTabScreen } from "./BottomTab";
import Splash from "../screens/Splash";
import Onboarding from "../screens/Onboarding";
import Login from "../screens/Login";
import ForgotPassword from "../screens/ForgotPassword";
import Notifications from "../screens/Notifications";
import TermsOfUse from "../screens/TermsOfUse";
import PrivacyPolicy from "../screens/PrivacyPolicy";
import Writing from "../screens/Writing/Writing";
import WritingLyrics from "../screens/Writing/WritingLyrics";
const screenOptions = {
headerShown: false,
cardOverlayEnabled: true,
headerStyle: {
backgroundColor: Palette.background,
},
headerTitleStyle: {},
headerTitleAlign: "center",
headerBackTitleVisible: false,
};
const MainStack = createStackNavigator();
const screens = [
{ name: Routes.Splash, component: Splash },
{ name: Routes.Onboarding, component: Onboarding },
{ name: Routes.Login, component: Login, title: "Connexion" },
{
name: Routes.ForgotPassword,
component: ForgotPassword,
title: "Mot de passe oublié",
},
{
name: Routes.BottomTab,
component: BottomTabScreen,
options: { animationEnabled: false },
},
{
name: Routes.Notifications,
component: Notifications,
title: "Notifications",
},
{
name: Routes.TermsOfUse,
component: TermsOfUse,
title: "Conditions d'utilisation",
},
{
name: Routes.PrivacyPolicy,
component: PrivacyPolicy,
title: "Politique de confidentialité",
},
{
name: Routes.Writing,
component: Writing,
},
{
name: Routes.WritingLyrics,
component: WritingLyrics,
},
];
export default function Main() {
return (
<MainStack.Navigator
initialRouteName={Routes.Splash}
screenOptions={[
{
contentStyle: {
backgroundColor: Palette.white,
},
},
screenOptions,
]}
>
{screens.map((screen) => (
<MainStack.Screen
key={screen.name}
name={screen.name}
component={screen.component}
title={screen.title}
options={{ headerShown: false, ...screen.options }}
/>
))}
</MainStack.Navigator>
);
}
+30
View File
@@ -0,0 +1,30 @@
import React, { setGlobal } from "reactn";
import { isDesktop } from "../hooks/useLayoutType";
import { Routes } from "./Routes";
export const navigationRef = React.createRef();
export function navigate(name, params) {
navigationRef.current?.navigate(name, params);
}
export function dispatch(route) {
navigationRef.current?.dispatch(route);
}
export function reset(route) {
navigationRef.current?.reset(route);
}
export function goBack() {
navigationRef.current?.goBack();
}
export const navigateToTask = (taskData = {}) => {
if (isDesktop) {
setGlobal({ currentTaskData: taskData });
} else {
navigate(Routes.TaskDetails, taskData);
}
};
+28
View File
@@ -0,0 +1,28 @@
export const Routes = {
Splash: "Splash",
Onboarding: "Onboarding",
Login: "Login",
ForgotPassword: "ForgotPassword",
BottomTab: "BottomTab",
Welcome: "Welcome",
Notifications: "Notifications",
HomeStack: "HomeStack",
Home: "Home",
ProjectEdit: "ProjectEdit",
ChatStack: "ChatStack",
Chat: "Chat",
SettingsStack: "SettingsStack",
Settings: "Settings",
ProjectSettings: "ProjectSettings",
AccountSettings: "AccountSettings",
TermsOfUse: "TermsOfUse",
PrivacyPolicy: "PrivacyPolicy",
Writing: "Writing",
WritingLyrics: "WritingLyrics",
};
+53
View File
@@ -0,0 +1,53 @@
import React from "react";
import { createStackNavigator } from "@react-navigation/stack";
import { Palette } from "../styles";
import { Routes } from "./Routes";
import Settings from "../screens/Settings";
import ProjectSettings from "../screens/ProjectSettings";
import AccountSettings from "../screens/AccountSettings";
const screenOptions = {
headerShown: false,
cardOverlayEnabled: true,
headerStyle: {
backgroundColor: Palette.background,
},
headerTitleAlign: "center",
headerBackTitleVisible: false,
};
const HomeStack = createStackNavigator();
export default () => {
return (
<HomeStack.Navigator
initialRouteName={Routes.Settings}
screenOptions={[
{
contentStyle: {
backgroundColor: Palette.white,
},
},
screenOptions,
]}
>
<HomeStack.Screen
name={Routes.Settings}
component={Settings}
options={{ headerShown: false }}
/>
<HomeStack.Screen
name={Routes.ProjectSettings}
component={ProjectSettings}
options={{ headerShown: false }}
/>
<HomeStack.Screen
name={Routes.AccountSettings}
component={AccountSettings}
options={{ headerShown: false }}
/>
</HomeStack.Navigator>
);
};
+85
View File
@@ -0,0 +1,85 @@
import React from "react";
import { View, TouchableOpacity } from "react-native";
import * as Haptics from "expo-haptics";
import { gutters, Palette, Style } from "../styles";
import useLayoutType from "../hooks/useLayoutType";
const TabBar = ({ state = {}, descriptors = {}, navigation = {} }) => {
const { isDesktop, windowWidth, mediumDesktopBreakpoint, isWeb } =
useLayoutType();
return (
<View
style={{
position: "absolute",
bottom: gutters * 2,
borderRadius: 500,
flexDirection: "row",
height: 60,
width: "60%",
alignSelf: "center",
maxWidth: isDesktop ? 200 : 220,
borderColor: Palette.ultraLightWhite,
borderWidth: 3,
paddingHorizontal: 1.2 * gutters,
backgroundColor: Palette.darkPurple,
...Style.containerSpaceBetween,
...Style.defaultShadows,
}}
>
{state?.routes?.map((route, index) => {
const { options } = descriptors[route.key];
const isFocused = state?.index === index;
const _onPressTabBar = () => {
if (!isWeb) {
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
}
const event = navigation.emit({
type: "tabPress",
target: route.key,
canPreventDefault: true,
});
if (!isFocused && !event.defaultPrevented) {
// The `merge: true` option makes sure that the params inside the tab screen are preserved
navigation.navigate({ name: route.name, merge: true });
}
};
const onLongPress = () => {
navigation.emit({
type: "tabLongPress",
target: route.key,
});
};
return (
!options?.hide && (
<TouchableOpacity
key={route.key}
style={{
alignSelf: "center",
width: `${100 / state?.routes?.length}%`,
height: 40,
...Style.containerCenter,
}}
accessibilityRole="button"
accessibilityState={isFocused ? { selected: true } : {}}
accessibilityLabel={options.tabBarAccessibilityLabel}
testID={options.tabBarTestID}
onPress={_onPressTabBar}
onLongPress={onLongPress}
>
{options?.tabBarIcon({ focused: isFocused })}
</TouchableOpacity>
)
);
})}
</View>
);
};
export default TabBar;
+41
View File
@@ -0,0 +1,41 @@
import React from "react";
import { createStackNavigator } from "@react-navigation/stack";
import { Palette } from "../styles";
import { Routes } from "./Routes";
import Tasks from "../screens/Tasks";
const screenOptions = {
headerShown: false,
cardOverlayEnabled: true,
headerStyle: {
backgroundColor: Palette.background,
},
headerTitleAlign: "center",
headerBackTitleVisible: false,
};
const HomeStack = createStackNavigator();
export default () => {
return (
<HomeStack.Navigator
initialRouteName={Routes.Tasks}
screenOptions={[
{
contentStyle: {
backgroundColor: Palette.white,
},
},
screenOptions,
]}
>
<HomeStack.Screen
name={Routes.Tasks}
component={Tasks}
options={{ headerShown: false }}
/>
</HomeStack.Navigator>
);
};
+4
View File
@@ -0,0 +1,4 @@
import {Routes} from './Routes';
import MainStack from './MainStack';
export {Routes, MainStack};