feature & fix

deskripsi:
feature :
- forumku

fix :
- forum index
- Back button : bisa custom icon
- Button custom : di tambah href
# No Issue
This commit is contained in:
2025-07-14 14:12:01 +08:00
parent ac9dae7c5b
commit fbde2fd031
8 changed files with 172 additions and 75 deletions

View File

@@ -93,6 +93,13 @@ export default function UserLayout() {
headerLeft: () => <BackButton />, headerLeft: () => <BackButton />,
}} }}
/> />
<Stack.Screen
name="forum/[id]/forumku"
options={{
title: "Forumku",
headerLeft: () => <BackButton icon={'close'} />,
}}
/>
{/* ========== Maps Section ========= */} {/* ========== Maps Section ========= */}
<Stack.Screen <Stack.Screen

View File

@@ -0,0 +1,42 @@
import {
AvatarCustom,
ButtonCustom,
CenterCustom,
Grid,
StackCustom,
TextCustom,
ViewWrapper,
} from "@/components";
import Forum_BerandaSection from "@/screens/Forum/berandaSection";
import { useLocalSearchParams } from "expo-router";
export default function Forumku() {
const { id } = useLocalSearchParams();
return (
<ViewWrapper>
<StackCustom>
<CenterCustom>
<AvatarCustom
href={`/(application)/(image)/preview-image/${id}`}
size="xl"
/>
</CenterCustom>
<Grid>
<Grid.Col span={6}>
<TextCustom bold truncate>
@bagas_banuna
</TextCustom>
<TextCustom>1 postingan</TextCustom>
</Grid.Col>
<Grid.Col span={6} style={{ alignItems: "flex-end" }}>
<ButtonCustom href={`/profile/${id}`}>
Kunjungi Profile
</ButtonCustom>
</Grid.Col>
</Grid>
<Forum_BerandaSection />
</StackCustom>
</ViewWrapper>
);
}

View File

@@ -9,16 +9,17 @@ import { MainColor } from "@/constants/color-palet";
import { ICON_SIZE_SMALL } from "@/constants/constans-value"; import { ICON_SIZE_SMALL } from "@/constants/constans-value";
import Forum_BerandaSection from "@/screens/Forum/berandaSection"; import Forum_BerandaSection from "@/screens/Forum/berandaSection";
import { Ionicons } from "@expo/vector-icons"; import { Ionicons } from "@expo/vector-icons";
import { router, Stack } from "expo-router"; import { router, Stack, useLocalSearchParams } from "expo-router";
export default function Forum() { export default function Forum() {
const { id } = useLocalSearchParams();
return ( return (
<> <>
<Stack.Screen <Stack.Screen
options={{ options={{
title: "Forum", title: "Forum",
headerLeft: () => <BackButton />, headerLeft: () => <BackButton />,
headerRight: () => <AvatarCustom />, headerRight: () => <AvatarCustom href={`/forum/${id}/forumku`}/>,
}} }}
/> />

View File

@@ -11,6 +11,7 @@
"@react-navigation/native": "^7.1.6", "@react-navigation/native": "^7.1.6",
"@react-navigation/native-stack": "^7.3.21", "@react-navigation/native-stack": "^7.3.21",
"@types/react-native-vector-icons": "^6.4.18", "@types/react-native-vector-icons": "^6.4.18",
"dayjs": "^1.11.13",
"expo": "53.0.17", "expo": "53.0.17",
"expo-blur": "~14.1.5", "expo-blur": "~14.1.5",
"expo-camera": "~16.1.10", "expo-camera": "~16.1.10",
@@ -703,6 +704,8 @@
"data-view-byte-offset": ["data-view-byte-offset@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" } }, "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ=="], "data-view-byte-offset": ["data-view-byte-offset@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" } }, "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ=="],
"dayjs": ["dayjs@1.11.13", "", {}, "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="],
"debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="], "debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
"decode-uri-component": ["decode-uri-component@0.2.2", "", {}, "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ=="], "decode-uri-component": ["decode-uri-component@0.2.2", "", {}, "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ=="],

View File

@@ -3,19 +3,33 @@ import { Ionicons } from "@expo/vector-icons";
import { Href, router } from "expo-router"; import { Href, router } from "expo-router";
/** /**
* *
* @param path - path to navigate to ? * @param path - path to navigate to ?
* @default router.back() * @default router.back()
* @returns if path : router.replace(path) else router.back() * @returns if path : router.replace(path) else router.back()
*/ */
const LeftButtonCustom = ({path}: {path?: Href}) => { const LeftButtonCustom = ({
path,
icon = "arrow-back",
iconCustom,
}: {
path?: Href;
icon?: React.ReactNode | any;
iconCustom?: React.ReactNode;
}) => {
return ( return (
<Ionicons <>
name="arrow-back" {iconCustom ? (
size={20} iconCustom
color={MainColor.yellow} ) : (
onPress={() => path ? router.replace(path) : router.back()} <Ionicons
/> name={icon}
size={20}
color={MainColor.yellow}
onPress={() => (path ? router.replace(path) : router.back())}
/>
)}
</>
); );
}; };

View File

@@ -5,6 +5,7 @@ import { StyleProp, Text, TouchableOpacity, ViewStyle } from "react-native";
import { radiusMap } from "@/constants/radius-value"; import { radiusMap } from "@/constants/radius-value";
import { MainColor } from "@/constants/color-palet"; import { MainColor } from "@/constants/color-palet";
import { stylesButton } from "./buttonCustomStyles"; import { stylesButton } from "./buttonCustomStyles";
import { Href, router } from "expo-router";
// Import radiusMap // Import radiusMap
@@ -13,6 +14,7 @@ type RadiusType = keyof typeof radiusMap | number;
interface ButtonProps { interface ButtonProps {
children?: React.ReactNode; children?: React.ReactNode;
href?: Href;
onPress?: () => void; onPress?: () => void;
title?: string; title?: string;
backgroundColor?: string; backgroundColor?: string;
@@ -25,6 +27,7 @@ interface ButtonProps {
const ButtonCustom: React.FC<ButtonProps> = ({ const ButtonCustom: React.FC<ButtonProps> = ({
children, children,
href,
onPress, onPress,
title = "Button", title = "Button",
backgroundColor = MainColor.yellow, backgroundColor = MainColor.yellow,
@@ -44,7 +47,13 @@ const ButtonCustom: React.FC<ButtonProps> = ({
: { backgroundColor }, : { backgroundColor },
style, style,
]} ]}
onPress={onPress} onPress={() => {
if (href) {
router.push(href);
} else {
onPress?.();
}
}}
disabled={disabled} disabled={disabled}
activeOpacity={0.8} activeOpacity={0.8}
> >

View File

@@ -18,6 +18,7 @@
"@react-navigation/native": "^7.1.6", "@react-navigation/native": "^7.1.6",
"@react-navigation/native-stack": "^7.3.21", "@react-navigation/native-stack": "^7.3.21",
"@types/react-native-vector-icons": "^6.4.18", "@types/react-native-vector-icons": "^6.4.18",
"dayjs": "^1.11.13",
"expo": "53.0.17", "expo": "53.0.17",
"expo-blur": "~14.1.5", "expo-blur": "~14.1.5",
"expo-camera": "~16.1.10", "expo-camera": "~16.1.10",

View File

@@ -1,76 +1,96 @@
import { BaseBox, Grid, AvatarCustom, TextCustom, ClickableCustom, Spacing } from "@/components"; import {
BaseBox,
Grid,
AvatarCustom,
TextCustom,
ClickableCustom,
Spacing,
} from "@/components";
import { MainColor } from "@/constants/color-palet"; import { MainColor } from "@/constants/color-palet";
import { ICON_SIZE_SMALL } from "@/constants/constans-value"; import { ICON_SIZE_SMALL } from "@/constants/constans-value";
import { Entypo, Ionicons } from "@expo/vector-icons"; import { Entypo, Ionicons } from "@expo/vector-icons";
import { View } from "react-native"; import { View } from "react-native";
import dayjs from "dayjs";
export default function Forum_BerandaSection() { export default function Forum_BerandaSection() {
return ( const dateNow = dayjs().format("DD/MM/YYYY")
<> return (
{Array.from({ length: 10 }).map((e, i) => ( <>
<BaseBox key={i}> {Array.from({ length: 10 }).map((e, i) => (
<View> <BaseBox key={i}>
<Grid> <View>
<Grid.Col span={2}> <Grid>
<AvatarCustom /> <Grid.Col span={2}>
</Grid.Col> <AvatarCustom />
<Grid.Col span={8}> </Grid.Col>
<TextCustom>Nama User</TextCustom> <Grid.Col span={8}>
<TextCustom bold size="small" color="green"> <TextCustom>Nama User</TextCustom>
Open <TextCustom bold size="small" color="green">
</TextCustom> Open
</Grid.Col> </TextCustom>
</Grid.Col>
<Grid.Col <Grid.Col
span={2} span={2}
style={{
justifyContent: "center",
}}
>
<ClickableCustom
onPress={() => {}}
style={{
alignItems: "flex-end",
}}
>
<Entypo
name="dots-three-horizontal"
color={MainColor.white}
size={ICON_SIZE_SMALL}
/>
</ClickableCustom>
</Grid.Col>
</Grid>
<View
style={{ style={{
backgroundColor: MainColor.soft_darkblue, justifyContent: "center",
padding: 8,
borderRadius: 8,
}} }}
> >
<TextCustom truncate={2}> <ClickableCustom
Lorem ipsum dolor sit amet consectetur adipisicing elit. Vitae onPress={() => {}}
inventore iure pariatur, libero omnis excepturi. Ullam ad style={{
officiis deleniti quos esse odit nesciunt, ipsam adipisci alignItems: "flex-end",
cumque aliquam corporis culpa fugit? }}
</TextCustom> >
</View> <Entypo
<Spacing /> name="dots-three-horizontal"
color={MainColor.white}
size={ICON_SIZE_SMALL}
/>
</ClickableCustom>
</Grid.Col>
</Grid>
<View <View
style={{ flexDirection: "row", alignItems: "center", gap: 10 }} style={{
> backgroundColor: MainColor.soft_darkblue,
<Ionicons padding: 8,
name="chatbubble-outline" borderRadius: 8,
size={ICON_SIZE_SMALL} }}
color={MainColor.white} >
/> <TextCustom truncate={2}>
<TextCustom>2</TextCustom> Lorem ipsum dolor sit amet consectetur adipisicing elit. Vitae
</View> inventore iure pariatur, libero omnis excepturi. Ullam ad
officiis deleniti quos esse odit nesciunt, ipsam adipisci cumque
aliquam corporis culpa fugit?
</TextCustom>
</View> </View>
</BaseBox> <Spacing />
))}
</> <Grid>
); <Grid.Col span={6}>
} <View
style={{
flexDirection: "row",
alignItems: "center",
gap: 10,
}}
>
<Ionicons
name="chatbubble-outline"
size={ICON_SIZE_SMALL}
color={MainColor.white}
/>
<TextCustom>2</TextCustom>
</View>
</Grid.Col>
<Grid.Col span={6} style={{ alignItems: "flex-end" }}>
<TextCustom size="small"> {dateNow}</TextCustom>
</Grid.Col>
</Grid>
</View>
</BaseBox>
))}
</>
);
}