Add UI for the Notification and History screens, as well as several components on the Home screen
This commit is contained in:
7
assets/icons/eazy_passport.svg
Normal file
7
assets/icons/eazy_passport.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M22 10.0833C23.7018 10.0833 25.334 10.7594 26.5373 11.9627C27.7407 13.1661 28.4167 14.7982 28.4167 16.5C28.4167 18.2018 27.7407 19.8339 26.5373 21.0372C25.334 22.2406 23.7018 22.9166 22 22.9166C20.2982 22.9166 18.6661 22.2406 17.4628 21.0372C16.2594 19.8339 15.5834 18.2018 15.5834 16.5C15.5834 14.7982 16.2594 13.1661 17.4628 11.9627C18.6661 10.7594 20.2982 10.0833 22 10.0833ZM10.0834 33.4583C10.0834 29.6633 15.4184 26.5833 22 26.5833C28.5817 26.5833 33.9167 29.6633 33.9167 33.4583V36.6666H10.0834V33.4583Z" fill="#237D96"/>
|
||||
<path d="M11.9717 15.4367C11.1467 14.9417 10.1933 14.6667 9.16667 14.6667C7.70798 14.6667 6.30903 15.2461 5.27758 16.2776C4.24613 17.309 3.66667 18.708 3.66667 20.1667C3.66667 21.6254 4.24613 23.0243 5.27758 24.0558C6.30903 25.0872 7.70798 25.6667 9.16667 25.6667C11.2933 25.6667 13.1267 24.4567 14.0433 22.6967C12.4667 20.6617 11.6967 18.0584 11.9717 15.4367Z" fill="#E5CC41"/>
|
||||
<path d="M0 33.9167V36.6667H6.41667V33.4584C6.41667 31.57 7.07667 29.8467 8.15833 28.6C3.465 29.2234 0 31.3684 0 33.9167Z" fill="#E5CC41"/>
|
||||
<path d="M38.7225 16.2776C37.6911 15.2461 36.2921 14.6667 34.8335 14.6667C33.8068 14.6667 32.8535 14.9417 32.0285 15.4367C32.2964 18.033 31.5545 20.6328 29.9568 22.6967C30.8735 24.4567 32.7068 25.6667 34.8335 25.6667C36.2921 25.6667 37.6911 25.0872 38.7225 24.0558C39.754 23.0243 40.3335 21.6254 40.3335 20.1667C40.3335 18.708 39.754 17.309 38.7225 16.2776Z" fill="#E5CC41"/>
|
||||
<path d="M37.5835 36.6667H44.0001V33.9167C44.0001 31.3684 40.5351 29.2234 35.8418 28.6C36.9235 29.8467 37.5835 31.57 37.5835 33.4584V36.6667Z" fill="#E5CC41"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
4
assets/icons/express_passport.svg
Normal file
4
assets/icons/express_passport.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="45" height="44" viewBox="0 0 45 44" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M22.3334 11C21.5817 12.1367 20.9584 13.365 20.5734 14.6667H24.0934C23.6997 13.3609 23.106 12.124 22.3334 11ZM19.9501 11.4034C18.2634 11.9717 16.8334 13.145 15.9901 14.6667H18.6667C18.9967 13.53 19.4001 12.43 19.9501 11.4034ZM24.6984 11.4034C25.2484 12.43 25.6701 13.53 26.0001 14.6667H28.6767C27.8334 13.145 26.3851 11.99 24.6984 11.4034ZM15.2384 16.5C15.0917 17.0867 15.0001 17.6917 15.0001 18.3334C15.0001 18.975 15.0917 19.58 15.2384 20.1667H18.3367C18.2634 19.5617 18.2084 18.9567 18.2084 18.3334C18.2084 17.71 18.2634 17.105 18.3367 16.5H15.2384ZM20.1884 16.5C20.0967 17.0867 20.0417 17.71 20.0417 18.3334C20.0417 18.9567 20.0967 19.5617 20.1884 20.1667H24.4784C24.5517 19.5617 24.6251 18.9567 24.6251 18.3334C24.6251 17.71 24.5517 17.0867 24.4784 16.5H20.1884ZM26.3301 16.5C26.4034 17.105 26.4584 17.71 26.4584 18.3334C26.4584 18.9567 26.4034 19.5617 26.3301 20.1667H29.4284C29.5751 19.58 29.6667 18.975 29.6667 18.3334C29.6667 17.6917 29.5751 17.0867 29.4284 16.5H26.3301ZM15.9901 22C16.8334 23.5217 18.2634 24.6767 19.9501 25.2634C19.4001 24.2367 18.9967 23.155 18.6667 22H15.9901ZM20.5734 22C20.9584 23.32 21.5817 24.53 22.3334 25.6667C23.1034 24.53 23.7084 23.32 24.0934 22H20.5734ZM26.0001 22C25.6701 23.155 25.2484 24.2367 24.6984 25.2634C26.3851 24.6767 27.8334 23.5217 28.6767 22H26.0001ZM11.3334 3.66669C10.3617 3.66669 9.42675 4.05169 8.74842 4.74835C8.05175 5.42669 7.66675 6.36169 7.66675 7.33335V36.6667C7.66675 37.6384 8.05175 38.5734 8.74842 39.2517C9.42675 39.9484 10.3617 40.3334 11.3334 40.3334H27.4667C26.5317 38.72 26.0001 36.8317 26.0001 34.8334H13.1667V31.1667H26.6234C28.1451 26.895 32.2151 23.8334 37.0001 23.8334V7.33335C37.0001 6.36169 36.6151 5.42669 35.9184 4.74835C35.2401 4.05169 34.3051 3.66669 33.3334 3.66669H11.3334ZM22.3334 9.16669C24.7717 9.16669 27.1001 10.1384 28.8234 11.8434C30.5284 13.5667 31.5001 15.895 31.5001 18.3334C31.5001 20.7717 30.5284 23.1 28.8234 24.8234C27.1001 26.5284 24.7717 27.5 22.3334 27.5C19.8951 27.5 17.5667 26.5284 15.8434 24.8234C14.1321 23.0964 13.1704 20.7646 13.1667 18.3334C13.1667 15.895 14.1384 13.5667 15.8434 11.8434C17.5667 10.1384 19.8951 9.16669 22.3334 9.16669Z" fill="#237D96"/>
|
||||
<path d="M38.8334 27.5H33.8334L29.6667 34.5H33.8334L32.5834 40.3333L38.8334 32.1667H35.5001L38.8334 27.5Z" fill="#E5CC41"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
6
assets/icons/guidebook.svg
Normal file
6
assets/icons/guidebook.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg width="45" height="44" viewBox="0 0 45 44" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M22.6667 39.4167C20.1917 37.8583 15.7 36.6667 12.5833 36.6667C9.55833 36.6667 6.44167 37.2167 3.875 38.5917C3.69167 38.6833 3.6 38.6833 3.41667 38.6833C2.95833 38.6833 2.5 38.225 2.5 37.7667V11C3.6 10.175 4.79167 9.625 6.16667 9.16667C8.20167 8.525 10.4383 8.25 12.5833 8.25C16.1583 8.25 20.0083 8.98333 22.6667 11C25.325 8.98333 29.175 8.25 32.75 8.25C34.895 8.25 37.1317 8.525 39.1667 9.16667C40.5417 9.625 41.7333 10.175 42.8333 11V37.7667C42.8333 38.225 42.375 38.6833 41.9167 38.6833C41.7333 38.6833 41.6417 38.6833 41.4583 38.5917C38.8917 37.2167 35.775 36.6667 32.75 36.6667C29.6333 36.6667 25.1417 37.8583 22.6667 39.4167ZM22.6667 14.6667V35.75C25.1417 34.1917 29.6333 33 32.75 33C34.95 33 37.15 33.275 39.1667 33.9167V12.8333C37.15 12.1917 34.95 11.9167 32.75 11.9167C29.6333 11.9167 25.1417 13.1083 22.6667 14.6667Z" fill="#237D96"/>
|
||||
<path d="M32.75 19.25C29.2667 19.25 26.535 19.8367 24.5 21.0833V18.04C26.755 17.0133 29.505 16.5 32.75 16.5C34.1983 16.5 35.7383 16.6467 37.3333 16.9217V19.7633C35.9767 19.415 34.4183 19.25 32.75 19.25Z" fill="#E5CC41"/>
|
||||
<path d="M24.5 22.8433C26.865 21.8717 29.615 21.395 32.75 21.395C34.1983 21.395 35.7383 21.5233 37.3333 21.8167V24.5667C36.1967 24.2733 34.6567 24.1267 32.75 24.1267C29.2667 24.1267 26.535 24.75 24.5 25.9417V22.8433Z" fill="#E5CC41"/>
|
||||
<path d="M32.75 26.2717C34.1983 26.2717 35.7383 26.4183 37.3333 26.7117V29.4617C36.1967 29.1683 34.6567 29.0217 32.75 29.0217C29.2667 29.0217 26.535 29.6267 24.5 30.8367V27.7383C26.645 26.7667 29.395 26.2717 32.75 26.2717Z" fill="#E5CC41"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
4
assets/icons/regular_passport.svg
Normal file
4
assets/icons/regular_passport.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11 3.66669C10.0276 3.66669 9.09495 4.053 8.40732 4.74063C7.71968 5.42826 7.33337 6.36089 7.33337 7.33335V36.6667C7.33337 37.6391 7.71968 38.5718 8.40732 39.2594C9.09495 39.947 10.0276 40.3334 11 40.3334H33C33.9725 40.3334 34.9051 39.947 35.5928 39.2594C36.2804 38.5718 36.6667 37.6391 36.6667 36.6667V7.33335C36.6667 6.36089 36.2804 5.42826 35.5928 4.74063C34.9051 4.053 33.9725 3.66669 33 3.66669H11ZM22 9.16669C24.4312 9.16669 26.7628 10.1325 28.4819 11.8515C30.2009 13.5706 31.1667 15.9022 31.1667 18.3334C31.1667 20.7645 30.2009 23.0961 28.4819 24.8152C26.7628 26.5342 24.4312 27.5 22 27.5C19.5689 27.5 17.2373 26.5342 15.5182 24.8152C13.7991 23.0961 12.8334 20.7645 12.8334 18.3334C12.8334 15.9022 13.7991 13.5706 15.5182 11.8515C17.2373 10.1325 19.5689 9.16669 22 9.16669ZM22 11C21.2484 12.1367 20.625 13.365 20.24 14.6667H23.76C23.3663 13.3609 22.7726 12.124 22 11ZM19.6167 11.4034C17.93 11.9717 16.5 13.145 15.6567 14.6667H18.3334C18.6634 13.53 19.0667 12.43 19.6167 11.4034ZM24.365 11.4034C24.915 12.43 25.3367 13.53 25.6667 14.6667H28.3434C27.5 13.145 26.0517 11.99 24.365 11.4034ZM14.905 16.5C14.7584 17.0867 14.6667 17.6917 14.6667 18.3334C14.6667 18.975 14.7584 19.58 14.905 20.1667H18.0034C17.93 19.5617 17.875 18.9567 17.875 18.3334C17.875 17.71 17.93 17.105 18.0034 16.5H14.905ZM19.855 16.5C19.7634 17.0867 19.7084 17.71 19.7084 18.3334C19.7084 18.9567 19.7634 19.5617 19.855 20.1667H24.145C24.2184 19.5617 24.2917 18.9567 24.2917 18.3334C24.2917 17.71 24.2184 17.0867 24.145 16.5H19.855ZM25.9967 16.5C26.07 17.105 26.125 17.71 26.125 18.3334C26.125 18.9567 26.07 19.5617 25.9967 20.1667H29.095C29.2417 19.58 29.3334 18.975 29.3334 18.3334C29.3334 17.6917 29.2417 17.0867 29.095 16.5H25.9967ZM15.6567 22C16.5 23.5217 17.93 24.6767 19.6167 25.2634C19.0667 24.2367 18.6634 23.155 18.3334 22H15.6567ZM20.24 22C20.625 23.32 21.2484 24.53 22 25.6667C22.77 24.53 23.375 23.32 23.76 22H20.24ZM25.6667 22C25.3367 23.155 24.915 24.2367 24.365 25.2634C26.0517 24.6767 27.5 23.5217 28.3434 22H25.6667ZM12.8334 31.1667H31.1667V34.8334H12.8334V31.1667Z" fill="#237D96"/>
|
||||
<rect x="12.8334" y="31.1667" width="18.3333" height="3.66667" fill="#E5CC41"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
3
assets/icons/waiting_for_payment.svg
Normal file
3
assets/icons/waiting_for_payment.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M13.125 12.615L14.955 13.6725L14.3925 14.6475L12 13.2675V10.5H13.125V12.615ZM18 12.75C18 15.6525 15.6525 18 12.75 18C9.8475 18 7.5 15.6525 7.5 12.75C7.5 12.495 7.5225 12.2475 7.56 12H1.5V3H15V8.01C16.77 8.8575 18 10.6575 18 12.75ZM8.01 10.5C8.145 10.23 8.2875 9.975 8.46 9.7275C8.3925 9.75 8.325 9.75 8.25 9.75C7.005 9.75 6 8.745 6 7.5C6 6.255 7.005 5.25 8.25 5.25C9.495 5.25 10.5 6.255 10.5 7.5C10.5 7.6875 10.47 7.875 10.425 8.0475C11.13 7.7025 11.9175 7.5 12.75 7.5C13.005 7.5 13.2525 7.5225 13.5 7.56V6C13.1022 6 12.7206 5.84196 12.4393 5.56066C12.158 5.27936 12 4.89782 12 4.5H4.5C4.5 5.3325 3.8325 6 3 6V9C3.39782 9 3.77936 9.15804 4.06066 9.43934C4.34196 9.72064 4.5 10.1022 4.5 10.5H8.01ZM16.5 12.75C16.5 10.68 14.82 9 12.75 9C10.68 9 9 10.68 9 12.75C9 14.82 10.68 16.5 12.75 16.5C14.82 16.5 16.5 14.82 16.5 12.75Z" fill="white"/>
|
||||
</svg>
|
After Width: | Height: | Size: 951 B |
BIN
assets/images/placeholderImageSlider.jpg
Normal file
BIN
assets/images/placeholderImageSlider.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.4 KiB |
@ -35,7 +35,7 @@ const Colors = StyleSheet.create({
|
||||
color: '#4F97AB',
|
||||
},
|
||||
secondary50: {
|
||||
color: '#7BB1C0,',
|
||||
color: '#7BB1C0',
|
||||
},
|
||||
secondary60: {
|
||||
color: '#A7CBD5',
|
||||
|
6
declarations.d.ts
vendored
Normal file
6
declarations.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
declare module '*.svg' {
|
||||
import React from 'react';
|
||||
import {SvgProps} from 'react-native-svg';
|
||||
const content: React.FC<SvgProps>;
|
||||
export default content;
|
||||
}
|
@ -1,11 +1,24 @@
|
||||
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
|
||||
|
||||
const defaultConfig = getDefaultConfig(__dirname);
|
||||
const {assetExts, sourceExts} = defaultConfig.resolver;
|
||||
|
||||
/**
|
||||
* Metro configuration
|
||||
* https://reactnative.dev/docs/metro
|
||||
*
|
||||
* @type {import('@react-native/metro-config').MetroConfig}
|
||||
* @type {import('metro-config').MetroConfig}
|
||||
*/
|
||||
const config = {};
|
||||
const config = {
|
||||
transformer: {
|
||||
babelTransformerPath: require.resolve(
|
||||
'react-native-svg-transformer/react-native',
|
||||
),
|
||||
},
|
||||
resolver: {
|
||||
assetExts: assetExts.filter(ext => ext !== 'svg'),
|
||||
sourceExts: [...sourceExts, 'svg'],
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = mergeConfig(getDefaultConfig(__dirname), config);
|
||||
module.exports = mergeConfig(defaultConfig, config);
|
||||
|
768
package-lock.json
generated
768
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -14,12 +14,15 @@
|
||||
"@react-navigation/elements": "^2.3.8",
|
||||
"@react-navigation/native": "^7.1.6",
|
||||
"@react-navigation/native-stack": "^7.3.10",
|
||||
"dayjs": "^1.11.13",
|
||||
"react": "19.0.0",
|
||||
"react-native": "0.78.0",
|
||||
"react-native-element-dropdown": "^2.12.4",
|
||||
"react-native-paper": "^5.13.2",
|
||||
"react-native-safe-area-context": "^5.4.0",
|
||||
"react-native-screens": "^4.10.0",
|
||||
"react-native-svg": "^15.11.2",
|
||||
"react-native-svg-transformer": "^1.5.0",
|
||||
"react-native-vector-icons": "^10.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
196
src/components/PassportAppointmentCard.tsx
Normal file
196
src/components/PassportAppointmentCard.tsx
Normal file
@ -0,0 +1,196 @@
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import WaitingForPaymentIcon from '../../assets/icons/waiting_for_payment.svg';
|
||||
import {StyleSheet, Text, View} from 'react-native';
|
||||
import FontFamily from '../../assets/styles/FontFamily';
|
||||
import Colors from '../../assets/styles/Colors';
|
||||
|
||||
type PassportAppointmentCardProps = {
|
||||
applicantName: string;
|
||||
applicantCount: number;
|
||||
appointmentDate: string;
|
||||
appointmentTime: string;
|
||||
serviceUnit: string;
|
||||
status: string;
|
||||
};
|
||||
|
||||
const renderStatusContent = (status: string) => {
|
||||
let backgroundColor;
|
||||
let IconComponent;
|
||||
|
||||
switch (status) {
|
||||
case 'Permohonan Kadaluarsa':
|
||||
backgroundColor = Colors.indicatorRed.color;
|
||||
IconComponent = () => (
|
||||
<Icon name="close" size={18} color={Colors.neutral100.color} />
|
||||
);
|
||||
break;
|
||||
case 'Sudah Terbayar':
|
||||
backgroundColor = Colors.indicatorGreen.color;
|
||||
IconComponent = () => (
|
||||
<Icon name="check" size={18} color={Colors.neutral100.color} />
|
||||
);
|
||||
break;
|
||||
default:
|
||||
backgroundColor = Colors.indicatorOrange.color;
|
||||
IconComponent = () => <WaitingForPaymentIcon width={18} height={18} />;
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{status === 'Sudah Terbayar' && (
|
||||
<View style={styles.seeRequirementsWrapper}>
|
||||
<Text style={styles.appointmentStatusText}>Lihat Persyaratan</Text>
|
||||
</View>
|
||||
)}
|
||||
<View style={[styles.appointmentStatusWrapper, {backgroundColor}]}>
|
||||
<IconComponent />
|
||||
<Text style={styles.appointmentStatusText}>{status}</Text>
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const PassportAppointmentCard: React.FC<PassportAppointmentCardProps> = ({
|
||||
applicantName,
|
||||
applicantCount,
|
||||
appointmentDate,
|
||||
appointmentTime,
|
||||
serviceUnit,
|
||||
status,
|
||||
}) => {
|
||||
return (
|
||||
<View style={styles.cardContainer}>
|
||||
<View style={styles.topCardContainer}>
|
||||
<View style={styles.topCardContentTextWrapper}>
|
||||
<Text style={styles.applicantNameText}>{applicantName}</Text>
|
||||
<Text style={styles.applicantCountText}>
|
||||
{applicantCount} Pemohon
|
||||
</Text>
|
||||
</View>
|
||||
<Icon name="menu-right" size={24} />
|
||||
</View>
|
||||
<View style={styles.midCardContainer}>
|
||||
<View style={styles.midCardContentWrapper}>
|
||||
<Icon
|
||||
name="calendar-today"
|
||||
size={24}
|
||||
color={Colors.secondary30.color}
|
||||
/>
|
||||
<Text style={styles.midCardContentTextStyle}>{appointmentDate}</Text>
|
||||
</View>
|
||||
<View style={styles.midCardContentWrapper}>
|
||||
<Icon
|
||||
name="clock-outline"
|
||||
size={24}
|
||||
color={Colors.secondary30.color}
|
||||
/>
|
||||
<Text style={styles.midCardContentTextStyle}>{appointmentTime}</Text>
|
||||
</View>
|
||||
<View style={styles.midCardContentWrapper}>
|
||||
<Icon
|
||||
name="map-marker-outline"
|
||||
size={24}
|
||||
color={Colors.secondary30.color}
|
||||
/>
|
||||
<Text style={styles.midCardContentTextStyle}>{serviceUnit}</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View>
|
||||
{status === 'Menunggu Pembayaran' && (
|
||||
<View style={styles.appointmentAlertWrapper}>
|
||||
<Text style={styles.appointmentAlertText}>
|
||||
Selesaikan pembayaran sebelum
|
||||
</Text>
|
||||
<Text style={styles.appointmentAlertText}>16 April 2025 23:30</Text>
|
||||
</View>
|
||||
)}
|
||||
<View style={styles.appointmentStatusContainer}>
|
||||
{renderStatusContent(status)}
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default PassportAppointmentCard;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
cardContainer: {
|
||||
borderRadius: 20,
|
||||
padding: 16,
|
||||
backgroundColor: Colors.neutral100.color,
|
||||
borderWidth: 1,
|
||||
borderColor: Colors.secondary50.color,
|
||||
},
|
||||
topCardContainer: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginVertical: 6,
|
||||
},
|
||||
topCardContentTextWrapper: {
|
||||
gap: 4,
|
||||
flex: 1,
|
||||
},
|
||||
applicantNameText: {
|
||||
fontSize: 14,
|
||||
...FontFamily.notoSansBold,
|
||||
textTransform: 'uppercase',
|
||||
color: Colors.secondary30.color,
|
||||
},
|
||||
applicantCountText: {
|
||||
fontSize: 12,
|
||||
...FontFamily.notoSansRegular,
|
||||
color: Colors.primary30.color,
|
||||
},
|
||||
midCardContainer: {
|
||||
gap: 8,
|
||||
marginVertical: 8,
|
||||
},
|
||||
midCardContentWrapper: {
|
||||
flexDirection: 'row',
|
||||
gap: 6,
|
||||
},
|
||||
midCardContentTextStyle: {
|
||||
fontSize: 12,
|
||||
...FontFamily.notoSansRegular,
|
||||
color: Colors.primary30.color,
|
||||
},
|
||||
appointmentAlertWrapper: {
|
||||
marginTop: 5,
|
||||
marginBottom: 13,
|
||||
},
|
||||
appointmentAlertText: {
|
||||
...FontFamily.notoSansRegular,
|
||||
fontSize: 10,
|
||||
color: Colors.indicatorRed.color,
|
||||
},
|
||||
appointmentStatusContainer: {
|
||||
alignItems: 'flex-end',
|
||||
justifyContent: 'flex-end',
|
||||
flexDirection: 'row',
|
||||
gap: 10,
|
||||
},
|
||||
appointmentStatusWrapper: {
|
||||
gap: 6,
|
||||
alignItems: 'center',
|
||||
backgroundColor: Colors.indicatorOrange.color,
|
||||
padding: 8,
|
||||
flexDirection: 'row',
|
||||
borderRadius: 8,
|
||||
},
|
||||
appointmentStatusText: {
|
||||
fontSize: 12,
|
||||
...FontFamily.notoSansMedium,
|
||||
color: Colors.neutral100.color,
|
||||
includeFontPadding: false,
|
||||
},
|
||||
seeRequirementsWrapper: {
|
||||
backgroundColor: Colors.primary30.color,
|
||||
borderRadius: 100,
|
||||
paddingHorizontal: 16,
|
||||
padding: 8,
|
||||
flexDirection: 'row',
|
||||
},
|
||||
});
|
49
src/data/History/PassportAppointmentData.tsx
Normal file
49
src/data/History/PassportAppointmentData.tsx
Normal file
@ -0,0 +1,49 @@
|
||||
const passportAppointmentData = [
|
||||
{
|
||||
id: '1',
|
||||
applicantName: 'Irma Wahyudini',
|
||||
applicantCount: 1,
|
||||
appointmentDate: 'Kamis, 17 April 2025',
|
||||
appointmentTime: '10.00 - 11.00 WIB',
|
||||
serviceUnit: 'Unit Layanan Paspor I Jakarta Selatan (Pondok Pinang)',
|
||||
status: 'Menunggu Pembayaran',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
applicantName: 'Salwa Aisyah Adhani',
|
||||
applicantCount: 2,
|
||||
appointmentDate: 'Senin, 14 April 2025',
|
||||
appointmentTime: '08:00 - 09:00 WIB',
|
||||
serviceUnit: 'Kantor Imigrasi Depok',
|
||||
status: 'Sudah Terbayar',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
applicantName: 'Salwa Aisyah Adhani',
|
||||
applicantCount: 2,
|
||||
appointmentDate: 'Senin, 14 April 2025',
|
||||
appointmentTime: '08:00 - 09:00 WIB',
|
||||
serviceUnit: 'Kantor Imigrasi Depok',
|
||||
status: 'Menunggu Pembayaran',
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
applicantName: 'Salwa Aisyah Adhani',
|
||||
applicantCount: 2,
|
||||
appointmentDate: 'Senin, 23 September 2024',
|
||||
appointmentTime: '10:00 - 11:00 WIB',
|
||||
serviceUnit: 'Kantor Imigrasi Depok',
|
||||
status: 'Permohonan Kadaluarsa',
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
applicantName: 'Yulfarisa Hasnah',
|
||||
applicantCount: 2,
|
||||
appointmentDate: 'Senin, 14 April 2025',
|
||||
appointmentTime: '08:00 - 09:00 WIB',
|
||||
serviceUnit: 'Kantor Imigrasi Depok',
|
||||
status: 'Sudah Terbayar',
|
||||
},
|
||||
];
|
||||
|
||||
export default passportAppointmentData;
|
91
src/data/Notification/NotificationData.tsx
Normal file
91
src/data/Notification/NotificationData.tsx
Normal file
@ -0,0 +1,91 @@
|
||||
const notificationData = [
|
||||
{
|
||||
id: '1',
|
||||
title: 'Pembayaran Permohonan',
|
||||
message:
|
||||
'Anda belum melakukan pembayaran untuk IRMA WAHYUDINI. Silakan melakukan pembayaran sebelum Selasa, 8 April 2025, pukul 23:33:03 WIB.',
|
||||
details:
|
||||
'Bila tidak melakukan pembayaran, maka permohonan Anda akan otomatis ditolak oleh sistem.',
|
||||
timestamp: '2025-04-19T10:50:00+07:00',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'Pembayaran Permohonan',
|
||||
message:
|
||||
'Anda belum melakukan pembayaran untuk MUHAMMAD AMMAR. Silakan melakukan pembayaran sebelum Minggu, 29 September 2024, pukul 23:33:03 WIB.',
|
||||
details:
|
||||
'Bila tidak melakukan pembayaran, maka permohonan Anda akan otomatis ditolak oleh sistem.',
|
||||
timestamp: '2024-09-27T00:00:00+07:00',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
title: 'Hari Penjadwalan',
|
||||
message:
|
||||
'Halo SALWA AISYAH ADHANI, hari ini adalah jadwal kunjungan Anda ke KANTOR IMIGRASI DEPOK pada sesi Senin, 7 November 2022, pukul 12:30-15:00 WIB.',
|
||||
details:
|
||||
'Kode Permohonan Anda adalah 2068000001633869. Pastikan Anda membawa dokumen yang dibutuhkan.',
|
||||
timestamp: '2022-11-07T00:00:00+07:00',
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
title: 'Dokumen Siap Diambil',
|
||||
message:
|
||||
'Dokumen paspor atas nama NURUL HUDA telah selesai diproses dan siap untuk diambil di KANTOR IMIGRASI YOGYAKARTA.',
|
||||
details:
|
||||
'Harap ambil dokumen dalam waktu 14 hari kerja sejak pemberitahuan ini.',
|
||||
timestamp: '2025-04-18T14:20:00+07:00',
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
title: 'Jadwal Ulang Permohonan',
|
||||
message:
|
||||
'Permohonan atas nama LUTFI HAKIM perlu dijadwalkan ulang karena adanya gangguan sistem.',
|
||||
details:
|
||||
'Silakan pilih jadwal baru melalui aplikasi sebelum Jumat, 21 April 2025.',
|
||||
timestamp: '2025-04-17T09:10:00+07:00',
|
||||
},
|
||||
{
|
||||
id: '6',
|
||||
title: 'Verifikasi Berhasil',
|
||||
message:
|
||||
'Verifikasi identitas untuk ANISA FITRIANI telah berhasil dilakukan.',
|
||||
details:
|
||||
'Anda dapat melanjutkan ke tahap selanjutnya yaitu pembayaran permohonan.',
|
||||
timestamp: '2025-04-16T13:45:00+07:00',
|
||||
},
|
||||
{
|
||||
id: '7',
|
||||
title: 'Permohonan Ditolak',
|
||||
message:
|
||||
'Permohonan atas nama RAKA ARDIANSYAH ditolak karena dokumen tidak lengkap.',
|
||||
details: 'Silakan ajukan ulang permohonan dengan dokumen yang sesuai.',
|
||||
timestamp: '2025-04-14T11:30:00+07:00',
|
||||
},
|
||||
{
|
||||
id: '8',
|
||||
title: 'Batas Waktu Pembayaran',
|
||||
message:
|
||||
'Pembayaran untuk permohonan atas nama SITI AMINAH akan berakhir dalam 1 jam.',
|
||||
details:
|
||||
'Pastikan pembayaran dilakukan sebelum batas waktu agar permohonan tidak dibatalkan.',
|
||||
timestamp: '2025-04-19T21:00:00+07:00',
|
||||
},
|
||||
{
|
||||
id: '9',
|
||||
title: 'Sesi Foto dan Biometrik',
|
||||
message:
|
||||
'Jadwal sesi foto dan biometrik atas nama DANIL MAULANA adalah pada Rabu, 23 April 2025 pukul 09:00 WIB.',
|
||||
details: 'Mohon hadir 15 menit lebih awal dengan membawa dokumen asli.',
|
||||
timestamp: '2025-04-20T08:00:00+07:00',
|
||||
},
|
||||
{
|
||||
id: '10',
|
||||
title: 'Pembayaran Berhasil',
|
||||
message:
|
||||
'Pembayaran untuk permohonan atas nama TIA ROSMAWATI telah berhasil.',
|
||||
details: 'Silakan menunggu informasi jadwal kedatangan.',
|
||||
timestamp: '2025-04-15T10:00:00+07:00',
|
||||
},
|
||||
];
|
||||
|
||||
export default notificationData;
|
@ -7,11 +7,11 @@ import {RootStackParamList} from '../../navigation/type';
|
||||
import {NativeStackNavigationProp} from '@react-navigation/native-stack';
|
||||
import {useNavigation} from '@react-navigation/native';
|
||||
import TextInputComponent from '../../components/TextInput';
|
||||
import genderData from '../../model/DropdownData/GenderData';
|
||||
import provinceData from '../../model/DropdownData/ProvinceData';
|
||||
import cityData from '../../model/DropdownData/CityData';
|
||||
import districtData from '../../model/DropdownData/DistrictData';
|
||||
import postalCodeData from '../../model/DropdownData/PostalCodeData';
|
||||
import genderData from '../../data/DropdownData/GenderData';
|
||||
import provinceData from '../../data/DropdownData/ProvinceData';
|
||||
import cityData from '../../data/DropdownData/CityData';
|
||||
import districtData from '../../data/DropdownData/DistrictData';
|
||||
import postalCodeData from '../../data/DropdownData/PostalCodeData';
|
||||
import {Button} from 'react-native-paper';
|
||||
|
||||
type EditProfileScreenNavigationProp = NativeStackNavigationProp<
|
||||
|
@ -1,21 +1,72 @@
|
||||
import React from 'react';
|
||||
import {StyleSheet, Text, View} from 'react-native';
|
||||
import {FlatList, StatusBar, Text, View} from 'react-native';
|
||||
import styles from './styles';
|
||||
import Colors from '../../../assets/styles/Colors';
|
||||
import passportAppointmentData from '../../data/History/PassportAppointmentData';
|
||||
import PassportAppointmentCard from '../../components/PassportAppointmentCard';
|
||||
import {useNavigation, useNavigationState} from '@react-navigation/native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {RootStackParamList} from '../../navigation/type';
|
||||
import {NativeStackNavigationProp} from '@react-navigation/native-stack';
|
||||
|
||||
type HistoryScreenNavigationProp = NativeStackNavigationProp<
|
||||
RootStackParamList,
|
||||
'History'
|
||||
>;
|
||||
|
||||
const ItemSeparator = () => <View style={styles.flatllistGap} />;
|
||||
|
||||
function HistoryScreen() {
|
||||
const navigation = useNavigation<HistoryScreenNavigationProp>();
|
||||
const previousRoute = useNavigationState(state => {
|
||||
const index = state.index;
|
||||
return index > 0 ? state.routes[index - 1].name : null;
|
||||
});
|
||||
|
||||
const showNavBackAppBar = previousRoute === 'NavigationRoute';
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text>History Screen</Text>
|
||||
<StatusBar
|
||||
backgroundColor={Colors.secondary30.color}
|
||||
barStyle="light-content"
|
||||
/>
|
||||
{showNavBackAppBar ? (
|
||||
<View style={styles.appBarNavBackContainer}>
|
||||
<Icon
|
||||
name="arrow-left"
|
||||
size={24}
|
||||
style={styles.appBarNavBackIcon}
|
||||
color={Colors.neutral100.color}
|
||||
onPress={() => navigation.goBack()}
|
||||
/>
|
||||
<Text style={styles.appBarNavBackTitle}>Riwayat</Text>
|
||||
</View>
|
||||
) : (
|
||||
<View style={styles.appBarContainer}>
|
||||
<Text style={styles.appBarTitle}>Riwayat</Text>
|
||||
</View>
|
||||
)}
|
||||
<View style={styles.topBackground} />
|
||||
<View style={styles.cardWrapper}>
|
||||
<FlatList
|
||||
data={passportAppointmentData}
|
||||
renderItem={({item}) => (
|
||||
<PassportAppointmentCard
|
||||
applicantName={item.applicantName}
|
||||
applicantCount={item.applicantCount}
|
||||
appointmentDate={item.appointmentDate}
|
||||
appointmentTime={item.appointmentTime}
|
||||
serviceUnit={item.serviceUnit}
|
||||
status={item.status}
|
||||
/>
|
||||
)}
|
||||
keyExtractor={item => item.id}
|
||||
ItemSeparatorComponent={ItemSeparator}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
});
|
||||
|
||||
export default HistoryScreen;
|
||||
|
52
src/screens/history/styles.tsx
Normal file
52
src/screens/history/styles.tsx
Normal file
@ -0,0 +1,52 @@
|
||||
import {StyleSheet} from 'react-native';
|
||||
import FontFamily from '../../../assets/styles/FontFamily';
|
||||
import Colors from '../../../assets/styles/Colors';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
appBarTitle: {
|
||||
color: Colors.neutral100.color,
|
||||
...FontFamily.notoSansExtraBold,
|
||||
fontSize: 28,
|
||||
marginStart: 16,
|
||||
includeFontPadding: false,
|
||||
},
|
||||
appBarContainer: {
|
||||
height: 64,
|
||||
backgroundColor: Colors.secondary30.color,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
appBarNavBackContainer: {
|
||||
height: 64,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
backgroundColor: Colors.secondary30.color,
|
||||
},
|
||||
appBarNavBackTitle: {
|
||||
color: Colors.neutral100.color,
|
||||
...FontFamily.notoSansRegular,
|
||||
fontSize: 22,
|
||||
marginStart: 16,
|
||||
},
|
||||
appBarNavBackIcon: {
|
||||
marginLeft: 16,
|
||||
},
|
||||
topBackground: {
|
||||
backgroundColor: Colors.secondary30.color,
|
||||
height: 85,
|
||||
alignItems: 'center',
|
||||
},
|
||||
cardWrapper: {
|
||||
margin: 16,
|
||||
marginBottom: 165,
|
||||
marginTop: -69,
|
||||
},
|
||||
flatllistGap: {
|
||||
height: 8,
|
||||
},
|
||||
});
|
||||
|
||||
export default styles;
|
@ -1,11 +1,109 @@
|
||||
import * as React from 'react';
|
||||
import styles from './styles';
|
||||
import {View, Text} from 'react-native';
|
||||
import {View, Text, StatusBar, FlatList} from 'react-native';
|
||||
import Colors from '../../../assets/styles/Colors';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {NativeStackNavigationProp} from '@react-navigation/native-stack';
|
||||
import {RootStackParamList} from '../../navigation/type';
|
||||
import {useNavigation} from '@react-navigation/native';
|
||||
import RegularPassportIcon from '../../../assets/icons/regular_passport.svg';
|
||||
import ExpressPassportIcon from '../../../assets/icons/express_passport.svg';
|
||||
import GuidebookIcon from '../../../assets/icons/guidebook.svg';
|
||||
import EazyPassportIcon from '../../../assets/icons/eazy_passport.svg';
|
||||
import passportAppointmentData from '../../data/History/PassportAppointmentData';
|
||||
import PassportAppointmentCard from '../../components/PassportAppointmentCard';
|
||||
|
||||
type HomeScreenNavigationProp = NativeStackNavigationProp<
|
||||
RootStackParamList,
|
||||
'Home'
|
||||
>;
|
||||
|
||||
const ItemSeparator = () => <View style={styles.flatllistGap} />;
|
||||
|
||||
const RenderContent = () => {
|
||||
const navigation = useNavigation<HomeScreenNavigationProp>();
|
||||
|
||||
return (
|
||||
<>
|
||||
<View style={styles.topContainer} />
|
||||
<View style={styles.serviceContainer}>
|
||||
<Text style={styles.serviceText}>Layanan</Text>
|
||||
<View style={styles.serviceOptionWrapper}>
|
||||
<View style={styles.serviceOptionContainer}>
|
||||
<View style={styles.serviceIcon}>
|
||||
<RegularPassportIcon />
|
||||
</View>
|
||||
<Text style={styles.serviceDesc}>Paspor Reguler</Text>
|
||||
</View>
|
||||
<View style={styles.serviceOptionContainer}>
|
||||
<View style={styles.serviceIcon}>
|
||||
<ExpressPassportIcon />
|
||||
</View>
|
||||
<Text style={styles.serviceDesc}>Paspor Percepatan</Text>
|
||||
</View>
|
||||
<View style={styles.serviceOptionContainer}>
|
||||
<View style={styles.serviceIcon}>
|
||||
<GuidebookIcon />
|
||||
</View>
|
||||
<Text style={styles.serviceDesc}>Buku Panduan</Text>
|
||||
</View>
|
||||
<View style={styles.serviceOptionContainer}>
|
||||
<View style={styles.serviceIcon}>
|
||||
<EazyPassportIcon />
|
||||
</View>
|
||||
<Text style={styles.serviceDesc}>EAZY Pasport</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.applicationStatusContainer}>
|
||||
<View style={styles.applicationStatusTextWrapper}>
|
||||
<Text style={styles.applicationStatusTitle}>Status Permohonan</Text>
|
||||
<Text
|
||||
style={styles.applicationStatusSeeAll}
|
||||
onPress={() => navigation.navigate('History')}>
|
||||
Lihat semua
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.cardWrapper}>
|
||||
<FlatList
|
||||
data={passportAppointmentData.slice(0, 2)}
|
||||
renderItem={({item}) => (
|
||||
<PassportAppointmentCard
|
||||
applicantName={item.applicantName}
|
||||
applicantCount={item.applicantCount}
|
||||
appointmentDate={item.appointmentDate}
|
||||
appointmentTime={item.appointmentTime}
|
||||
serviceUnit={item.serviceUnit}
|
||||
status={item.status}
|
||||
/>
|
||||
)}
|
||||
keyExtractor={item => item.id}
|
||||
ItemSeparatorComponent={ItemSeparator}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
function HomeScreen() {
|
||||
const navigation = useNavigation<HomeScreenNavigationProp>();
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text>Home Screen</Text>
|
||||
<StatusBar
|
||||
backgroundColor={Colors.secondary30.color}
|
||||
barStyle="light-content"
|
||||
/>
|
||||
<View style={styles.appBarContainer}>
|
||||
<Text style={styles.appBarTitle}>Halo, Salwa!</Text>
|
||||
<Icon
|
||||
name="bell-outline"
|
||||
size={24}
|
||||
color={Colors.neutral100.color}
|
||||
onPress={() => navigation.navigate('Notification')}
|
||||
/>
|
||||
</View>
|
||||
<FlatList data={[{}]} renderItem={() => <RenderContent />} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -1,19 +1,87 @@
|
||||
import {StyleSheet} from 'react-native';
|
||||
import Colors from '../../../assets/styles/Colors';
|
||||
import FontFamily from '../../../assets/styles/FontFamily';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
bottomNavLabel: {
|
||||
appBarTitle: {
|
||||
color: Colors.neutral100.color,
|
||||
...FontFamily.notoSansExtraBold,
|
||||
fontSize: 28,
|
||||
marginVertical: 14,
|
||||
},
|
||||
appBarContainer: {
|
||||
height: 64,
|
||||
backgroundColor: Colors.secondary30.color,
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 16,
|
||||
flexDirection: 'row',
|
||||
},
|
||||
topContainer: {
|
||||
backgroundColor: Colors.secondary30.color,
|
||||
height: 245,
|
||||
alignItems: 'center',
|
||||
},
|
||||
serviceContainer: {
|
||||
marginVertical: 12,
|
||||
marginHorizontal: 16,
|
||||
gap: 12,
|
||||
},
|
||||
serviceText: {
|
||||
color: Colors.primary30.color,
|
||||
...FontFamily.notoSansExtraBold,
|
||||
fontSize: 18,
|
||||
},
|
||||
serviceOptionWrapper: {
|
||||
flexDirection: 'row',
|
||||
gap: 10,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
serviceOptionContainer: {
|
||||
alignItems: 'center',
|
||||
marginHorizontal: 12,
|
||||
},
|
||||
serviceIcon: {
|
||||
padding: 8,
|
||||
backgroundColor: Colors.secondary70.color,
|
||||
borderRadius: 4,
|
||||
},
|
||||
serviceDesc: {
|
||||
width: 60,
|
||||
textAlign: 'center',
|
||||
alignSelf: 'center',
|
||||
fontSize: 10,
|
||||
marginTop: 8,
|
||||
color: Colors.primary30.color,
|
||||
...FontFamily.notoSansRegular,
|
||||
},
|
||||
applicationStatusContainer: {
|
||||
marginHorizontal: 16,
|
||||
},
|
||||
applicationStatusTextWrapper: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
marginVertical: 12,
|
||||
alignItems: 'center',
|
||||
},
|
||||
applicationStatusTitle: {
|
||||
color: Colors.primary30.color,
|
||||
...FontFamily.notoSansExtraBold,
|
||||
fontSize: 18,
|
||||
},
|
||||
applicationStatusSeeAll: {
|
||||
color: Colors.secondary30.color,
|
||||
fontSize: 12,
|
||||
position: 'absolute',
|
||||
...FontFamily.notoSansSemiBold,
|
||||
},
|
||||
cardWrapper: {
|
||||
marginBottom: 16,
|
||||
},
|
||||
flatllistGap: {
|
||||
height: 8,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -1,21 +1,86 @@
|
||||
import React from 'react';
|
||||
import {StyleSheet, Text, View} from 'react-native';
|
||||
import {FlatList, StatusBar, Text, View} from 'react-native';
|
||||
import Colors from '../../../assets/styles/Colors';
|
||||
import styles from './styles';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {RootStackParamList} from '../../navigation/type';
|
||||
import {NativeStackNavigationProp} from '@react-navigation/native-stack';
|
||||
import {useNavigation} from '@react-navigation/native';
|
||||
import dayjs from 'dayjs';
|
||||
import 'dayjs/locale/id';
|
||||
import notificationData from '../../data/Notification/NotificationData';
|
||||
|
||||
type NotificationScreenNavigationProp = NativeStackNavigationProp<
|
||||
RootStackParamList,
|
||||
'Notification'
|
||||
>;
|
||||
|
||||
type NotificationCardProps = {
|
||||
title: string;
|
||||
message: string;
|
||||
details: string;
|
||||
timestamp: string;
|
||||
};
|
||||
|
||||
const NotificationCard: React.FC<NotificationCardProps> = ({
|
||||
title,
|
||||
message,
|
||||
details,
|
||||
timestamp,
|
||||
}) => {
|
||||
dayjs.locale('id');
|
||||
const formattedTime = dayjs(timestamp).format('D MMMM YYYY');
|
||||
return (
|
||||
<View style={styles.cardContainer}>
|
||||
<View style={styles.topCardContentWrapper}>
|
||||
<Text style={styles.notificationTitle}>{title}</Text>
|
||||
<Text style={styles.notificationTime}>{formattedTime}</Text>
|
||||
</View>
|
||||
<Text style={styles.notificationMessage}>{message}</Text>
|
||||
<Text style={styles.notificationDetail}>{details}</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const ItemSeparator = () => <View style={styles.flatllistGap} />;
|
||||
|
||||
function NotificationScreen() {
|
||||
const navigation = useNavigation<NotificationScreenNavigationProp>();
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text>Notification Screen</Text>
|
||||
<StatusBar
|
||||
backgroundColor={Colors.secondary30.color}
|
||||
barStyle="light-content"
|
||||
/>
|
||||
<View style={styles.appBarContainer}>
|
||||
<Icon
|
||||
name="arrow-left"
|
||||
size={24}
|
||||
style={styles.appBarIcon}
|
||||
color={Colors.neutral100.color}
|
||||
onPress={() => navigation.goBack()}
|
||||
/>
|
||||
<Text style={styles.appBarTitle}>Notifikasi</Text>
|
||||
</View>
|
||||
<View style={styles.topBackground} />
|
||||
<View style={styles.cardWrapper}>
|
||||
<FlatList
|
||||
data={notificationData}
|
||||
renderItem={({item}) => (
|
||||
<NotificationCard
|
||||
title={item.title}
|
||||
message={item.message}
|
||||
details={item.details}
|
||||
timestamp={item.timestamp}
|
||||
/>
|
||||
)}
|
||||
keyExtractor={item => item.id}
|
||||
ItemSeparatorComponent={ItemSeparator}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
});
|
||||
|
||||
export default NotificationScreen;
|
||||
|
70
src/screens/notification/styles.tsx
Normal file
70
src/screens/notification/styles.tsx
Normal file
@ -0,0 +1,70 @@
|
||||
import {StyleSheet} from 'react-native';
|
||||
import Colors from '../../../assets/styles/Colors';
|
||||
import FontFamily from '../../../assets/styles/FontFamily';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
appBarTitle: {
|
||||
color: Colors.neutral100.color,
|
||||
...FontFamily.notoSansRegular,
|
||||
fontSize: 22,
|
||||
marginStart: 16,
|
||||
},
|
||||
appBarIcon: {
|
||||
marginLeft: 16,
|
||||
},
|
||||
appBarContainer: {
|
||||
height: 64,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
backgroundColor: Colors.secondary30.color,
|
||||
},
|
||||
topBackground: {
|
||||
backgroundColor: Colors.secondary30.color,
|
||||
height: 85,
|
||||
alignItems: 'center',
|
||||
},
|
||||
cardWrapper: {
|
||||
margin: 16,
|
||||
marginBottom: 165,
|
||||
marginTop: -69,
|
||||
},
|
||||
cardContainer: {
|
||||
borderRadius: 8,
|
||||
padding: 16,
|
||||
backgroundColor: Colors.neutral100.color,
|
||||
borderWidth: 1,
|
||||
borderColor: Colors.secondary50.color,
|
||||
},
|
||||
topCardContentWrapper: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
},
|
||||
flatllistGap: {
|
||||
height: 8,
|
||||
},
|
||||
notificationTitle: {
|
||||
fontSize: 14,
|
||||
...FontFamily.notoSansBold,
|
||||
},
|
||||
notificationMessage: {
|
||||
fontSize: 12,
|
||||
marginTop: 4,
|
||||
...FontFamily.notoSansRegular,
|
||||
},
|
||||
notificationDetail: {
|
||||
fontSize: 12,
|
||||
marginTop: 4,
|
||||
...FontFamily.notoSansRegular,
|
||||
},
|
||||
notificationTime: {
|
||||
fontSize: 10,
|
||||
...FontFamily.notoSansRegular,
|
||||
},
|
||||
});
|
||||
|
||||
export default styles;
|
@ -8,7 +8,7 @@ import styles from './styles';
|
||||
import TextInputComponent from '../../components/TextInput';
|
||||
import {Button, Checkbox} from 'react-native-paper';
|
||||
import Colors from '../../../assets/styles/Colors';
|
||||
import genderData from '../../model/DropdownData/GenderData';
|
||||
import genderData from '../../data/DropdownData/GenderData';
|
||||
|
||||
type RegisterScreenNavigationProp = NativeStackNavigationProp<
|
||||
RootStackParamList,
|
||||
|
Reference in New Issue
Block a user