Deskripsi:
- new comp : Radio - fix comp : Text area > placeholder diatas - fix page : report forum sudah pakai radio # No Issue
This commit is contained in:
@@ -11,7 +11,7 @@ import {
|
|||||||
} from "@/components";
|
} from "@/components";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
import Forum_BoxDetailSection from "@/screens/Forum/DiscussionBoxSection";
|
import Forum_BoxDetailSection from "@/screens/Forum/DiscussionBoxSection";
|
||||||
import { listDataDummyCommentarForum } from "@/screens/Forum/list-data-dummy";
|
import { listDummyDiscussionForum } from "@/screens/Forum/list-data-dummy";
|
||||||
import Forum_MenuDrawerBerandaSection from "@/screens/Forum/MenuDrawerSection.tsx/MenuBeranda";
|
import Forum_MenuDrawerBerandaSection from "@/screens/Forum/MenuDrawerSection.tsx/MenuBeranda";
|
||||||
import { useLocalSearchParams } from "expo-router";
|
import { useLocalSearchParams } from "expo-router";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
@@ -47,12 +47,14 @@ export default function Forumku() {
|
|||||||
</ButtonCustom>
|
</ButtonCustom>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
</Grid>
|
</Grid>
|
||||||
{listDataDummyCommentarForum.map((e, i) => (
|
{listDummyDiscussionForum.map((e, i) => (
|
||||||
<Forum_BoxDetailSection
|
<Forum_BoxDetailSection
|
||||||
key={i}
|
key={i}
|
||||||
data={e}
|
data={e}
|
||||||
setOpenDrawer={setOpenDrawer}
|
setOpenDrawer={setOpenDrawer}
|
||||||
setStatus={setStatus}
|
setStatus={setStatus}
|
||||||
|
isTruncate={true}
|
||||||
|
href={`/forum/${id}`}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import {
|
import {
|
||||||
AlertCustom,
|
AlertCustom,
|
||||||
ButtonCustom,
|
ButtonCustom,
|
||||||
DrawerCustom,
|
DrawerCustom,
|
||||||
Spacing,
|
Spacing,
|
||||||
TextAreaCustom,
|
TextAreaCustom,
|
||||||
ViewWrapper
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
import Forum_CommentarBoxSection from "@/screens/Forum/CommentarBoxSection";
|
import Forum_CommentarBoxSection from "@/screens/Forum/CommentarBoxSection";
|
||||||
@@ -26,6 +26,7 @@ export default function ForumDetail() {
|
|||||||
|
|
||||||
// Comentar
|
// Comentar
|
||||||
const [openDrawerCommentar, setOpenDrawerCommentar] = useState(false);
|
const [openDrawerCommentar, setOpenDrawerCommentar] = useState(false);
|
||||||
|
const [alertDeleteCommentar, setAlertDeleteCommentar] = useState(false);
|
||||||
|
|
||||||
const dataDummy = {
|
const dataDummy = {
|
||||||
name: "Bagas",
|
name: "Bagas",
|
||||||
@@ -76,7 +77,6 @@ export default function ForumDetail() {
|
|||||||
key={i}
|
key={i}
|
||||||
data={e}
|
data={e}
|
||||||
setOpenDrawer={setOpenDrawerCommentar}
|
setOpenDrawer={setOpenDrawerCommentar}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
@@ -148,23 +148,23 @@ export default function ForumDetail() {
|
|||||||
setIsDrawerOpen={() => {
|
setIsDrawerOpen={() => {
|
||||||
setOpenDrawerCommentar(false);
|
setOpenDrawerCommentar(false);
|
||||||
}}
|
}}
|
||||||
setShowDeleteAlert={setDeleteAlert}
|
setShowDeleteAlert={setAlertDeleteCommentar}
|
||||||
/>
|
/>
|
||||||
</DrawerCustom>
|
</DrawerCustom>
|
||||||
|
|
||||||
{/* Alert Delete Commentar */}
|
{/* Alert Delete Commentar */}
|
||||||
<AlertCustom
|
<AlertCustom
|
||||||
isVisible={deleteAlert}
|
isVisible={alertDeleteCommentar}
|
||||||
title="Hapus Komentar"
|
title="Hapus Komentar"
|
||||||
message="Apakah Anda yakin ingin menghapus komentar ini?"
|
message="Apakah Anda yakin ingin menghapus komentar ini?"
|
||||||
onLeftPress={() => {
|
onLeftPress={() => {
|
||||||
setOpenDrawerCommentar(false);
|
setOpenDrawerCommentar(false);
|
||||||
setDeleteAlert(false);
|
setAlertDeleteCommentar(false);
|
||||||
console.log("Batal");
|
console.log("Batal");
|
||||||
}}
|
}}
|
||||||
onRightPress={() => {
|
onRightPress={() => {
|
||||||
setOpenDrawerCommentar(false);
|
setOpenDrawerCommentar(false);
|
||||||
setDeleteAlert(false);
|
setAlertDeleteCommentar(false);
|
||||||
console.log("Hapus commentar");
|
console.log("Hapus commentar");
|
||||||
}}
|
}}
|
||||||
textLeft="Batal"
|
textLeft="Batal"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
ButtonCustom,
|
ButtonCustom,
|
||||||
|
Spacing,
|
||||||
StackCustom,
|
StackCustom,
|
||||||
ViewWrapper
|
ViewWrapper
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
@@ -33,6 +34,7 @@ export default function ForumReportCommentar() {
|
|||||||
>
|
>
|
||||||
Lainnya
|
Lainnya
|
||||||
</ButtonCustom>
|
</ButtonCustom>
|
||||||
|
<Spacing/>
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ViewWrapper, StackCustom, ButtonCustom } from "@/components";
|
import { ViewWrapper, StackCustom, ButtonCustom, Spacing } from "@/components";
|
||||||
import { MainColor, AccentColor } from "@/constants/color-palet";
|
import { MainColor, AccentColor } from "@/constants/color-palet";
|
||||||
import Forum_ReportListSection from "@/screens/Forum/ReportListSection";
|
import Forum_ReportListSection from "@/screens/Forum/ReportListSection";
|
||||||
import { router } from "expo-router";
|
import { router } from "expo-router";
|
||||||
@@ -29,6 +29,7 @@ export default function ForumReportPosting() {
|
|||||||
>
|
>
|
||||||
Lainnya
|
Lainnya
|
||||||
</ButtonCustom>
|
</ButtonCustom>
|
||||||
|
<Spacing />
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
</>
|
</>
|
||||||
|
|||||||
132
components/Radio/RadioCustom.tsx
Normal file
132
components/Radio/RadioCustom.tsx
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
// components/Radio.tsx
|
||||||
|
import { GStyles } from '@/styles/global-styles';
|
||||||
|
import React, { createContext, useCallback, useContext } from 'react';
|
||||||
|
import {
|
||||||
|
StyleSheet,
|
||||||
|
Text,
|
||||||
|
TextStyle,
|
||||||
|
TouchableOpacity,
|
||||||
|
View,
|
||||||
|
ViewStyle
|
||||||
|
} from 'react-native';
|
||||||
|
|
||||||
|
// ========================
|
||||||
|
// Types
|
||||||
|
// ========================
|
||||||
|
|
||||||
|
type RadioContextType = {
|
||||||
|
value: string;
|
||||||
|
onChange: (value: string) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const RadioContext = createContext<RadioContextType | undefined>(undefined);
|
||||||
|
|
||||||
|
interface RadioGroupProps {
|
||||||
|
value: string;
|
||||||
|
onChange: (value: string) => void;
|
||||||
|
children: React.ReactNode;
|
||||||
|
style?: ViewStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RadioProps {
|
||||||
|
label: string;
|
||||||
|
value: string | number;
|
||||||
|
disabled?: boolean;
|
||||||
|
style?: ViewStyle;
|
||||||
|
labelStyle?: TextStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================
|
||||||
|
// Components
|
||||||
|
// ========================
|
||||||
|
|
||||||
|
export const RadioGroup: React.FC<RadioGroupProps> = ({ value, onChange, children, style }) => {
|
||||||
|
const contextValue = {
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
};
|
||||||
|
|
||||||
|
return <RadioContext.Provider value={contextValue}>{children}</RadioContext.Provider>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const RadioCustom: React.FC<RadioProps> = ({ label, value, disabled = false, style, labelStyle }) => {
|
||||||
|
const context = useContext(RadioContext);
|
||||||
|
if (!context) {
|
||||||
|
throw new Error('Radio must be used inside a RadioGroup');
|
||||||
|
}
|
||||||
|
|
||||||
|
const { value: selectedValue, onChange } = context;
|
||||||
|
|
||||||
|
const handlePress = useCallback(() => {
|
||||||
|
if (!disabled && selectedValue !== value) {
|
||||||
|
onChange(value as any);
|
||||||
|
}
|
||||||
|
}, [disabled, selectedValue, value, onChange]);
|
||||||
|
|
||||||
|
const isSelected = selectedValue === value;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[styles.radioContainer, style]}
|
||||||
|
onPress={handlePress}
|
||||||
|
disabled={disabled}
|
||||||
|
>
|
||||||
|
{/* Circle */}
|
||||||
|
<View
|
||||||
|
style={[styles.outerCircle, isSelected && styles.outerCircleChecked]}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={[styles.innerCircle, isSelected && styles.innerCircleChecked]}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Label */}
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
GStyles.textLabelBold,
|
||||||
|
labelStyle,
|
||||||
|
disabled && GStyles.inputTextDisabled,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ========================
|
||||||
|
// Styles
|
||||||
|
// ========================
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
radioContainer: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginVertical: 8,
|
||||||
|
},
|
||||||
|
outerCircle: {
|
||||||
|
height: 24,
|
||||||
|
width: 24,
|
||||||
|
borderRadius: 12,
|
||||||
|
borderWidth: 2,
|
||||||
|
borderColor: '#3B82F6',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
outerCircleChecked: {
|
||||||
|
backgroundColor: '#3B82F6',
|
||||||
|
},
|
||||||
|
innerCircle: {
|
||||||
|
height: 12,
|
||||||
|
width: 12,
|
||||||
|
borderRadius: 6,
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
},
|
||||||
|
innerCircleChecked: {
|
||||||
|
backgroundColor: 'white',
|
||||||
|
borderColor: 'white',
|
||||||
|
borderRadius: 6,
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
@@ -105,7 +105,7 @@ const TextAreaCustom: React.FC<TextAreaCustomProps> = ({
|
|||||||
multiline
|
multiline
|
||||||
numberOfLines={numberOfLines}
|
numberOfLines={numberOfLines}
|
||||||
style={[
|
style={[
|
||||||
GStyles.inputText,
|
// GStyles.inputText,
|
||||||
GStyles.textAreaInput,
|
GStyles.textAreaInput,
|
||||||
{ color: fontColor },
|
{ color: fontColor },
|
||||||
]}
|
]}
|
||||||
|
|||||||
@@ -1,18 +1,39 @@
|
|||||||
import { BaseBox, StackCustom, TextCustom } from "@/components";
|
import { BaseBox, ButtonCustom, StackCustom, TextCustom } from "@/components";
|
||||||
|
import { RadioCustom, RadioGroup } from "@/components/Radio/RadioCustom";
|
||||||
|
import { MainColor } from "@/constants/color-palet";
|
||||||
import { listDummyReportForum } from "@/lib/dummy-data/forum/report-list";
|
import { listDummyReportForum } from "@/lib/dummy-data/forum/report-list";
|
||||||
|
import { router } from "expo-router";
|
||||||
|
import { useState } from "react";
|
||||||
import { View } from "react-native";
|
import { View } from "react-native";
|
||||||
|
|
||||||
export default function Forum_ReportListSection() {
|
export default function Forum_ReportListSection() {
|
||||||
|
const [value, setValue] = useState<any | number>("");
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<BaseBox>
|
<BaseBox>
|
||||||
<StackCustom>
|
<StackCustom>
|
||||||
{listDummyReportForum.map((e, i) => (
|
<RadioGroup value={value} onChange={setValue}>
|
||||||
<View key={i}>
|
{listDummyReportForum.map((e, i) => (
|
||||||
<TextCustom>{e.title}</TextCustom>
|
<View key={i}>
|
||||||
<TextCustom>{e.desc}</TextCustom>
|
<RadioCustom
|
||||||
</View>
|
label={e.title}
|
||||||
))}
|
// value={i}
|
||||||
|
value={e.title}
|
||||||
|
/>
|
||||||
|
<TextCustom>{e.desc}</TextCustom>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</RadioGroup>
|
||||||
|
|
||||||
|
{/* <ButtonCustom
|
||||||
|
backgroundColor={MainColor.red}
|
||||||
|
textColor={MainColor.white}
|
||||||
|
onPress={() => {
|
||||||
|
console.log("Report", value);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Report
|
||||||
|
</ButtonCustom> */}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</BaseBox>
|
</BaseBox>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -44,17 +44,16 @@ export const GStyles = StyleSheet.create({
|
|||||||
},
|
},
|
||||||
floatingContainer: {
|
floatingContainer: {
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
bottom: 80,
|
bottom: 100,
|
||||||
right: 20,
|
right: 20,
|
||||||
zIndex: 8,
|
zIndex: 8,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Style saat disabled
|
// =============== Disabled Styles =============== //
|
||||||
disabledBox: {
|
disabledBox: {
|
||||||
backgroundColor: MainColor.disabled,
|
backgroundColor: MainColor.disabled,
|
||||||
borderColor: AccentColor.disabledBorder,
|
borderColor: AccentColor.disabledBorder,
|
||||||
},
|
},
|
||||||
|
|
||||||
inputDisabled: {
|
inputDisabled: {
|
||||||
backgroundColor: "#f0f0f0",
|
backgroundColor: "#f0f0f0",
|
||||||
borderColor: "#ddd",
|
borderColor: "#ddd",
|
||||||
@@ -65,7 +64,7 @@ export const GStyles = StyleSheet.create({
|
|||||||
inputPlaceholderDisabled: {
|
inputPlaceholderDisabled: {
|
||||||
color: "#444",
|
color: "#444",
|
||||||
},
|
},
|
||||||
// =============== Main Styles =============== //
|
// =============== Disabled Styles =============== //
|
||||||
|
|
||||||
// =============== AUTHENTICATION =============== //
|
// =============== AUTHENTICATION =============== //
|
||||||
authContainer: {
|
authContainer: {
|
||||||
@@ -94,6 +93,11 @@ export const GStyles = StyleSheet.create({
|
|||||||
color: MainColor.white_gray,
|
color: MainColor.white_gray,
|
||||||
fontWeight: "normal",
|
fontWeight: "normal",
|
||||||
},
|
},
|
||||||
|
textLabelBold: {
|
||||||
|
fontSize: TEXT_SIZE_MEDIUM,
|
||||||
|
color: MainColor.white_gray,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
// =============== TEXT & LABEL =============== //
|
// =============== TEXT & LABEL =============== //
|
||||||
|
|
||||||
// =============== STACK HEADER =============== //
|
// =============== STACK HEADER =============== //
|
||||||
@@ -284,8 +288,10 @@ export const GStyles = StyleSheet.create({
|
|||||||
// TextArea untuk tambahan
|
// TextArea untuk tambahan
|
||||||
textAreaInput: {
|
textAreaInput: {
|
||||||
textAlignVertical: "top",
|
textAlignVertical: "top",
|
||||||
padding: 5,
|
paddingTop: 10,
|
||||||
height: undefined, // biar multiline bebas tinggi
|
// height: undefined, // biar multiline bebas tinggi
|
||||||
|
height: 100,
|
||||||
|
width: "100%",
|
||||||
},
|
},
|
||||||
|
|
||||||
// Select
|
// Select
|
||||||
|
|||||||
Reference in New Issue
Block a user