Commit 9d293bda by tungnq

TODO: Đã cấu hình xong cho android đã chạy thử nghiệm test thành công

parent 6efbfc0e
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: ['react-native-reanimated/plugin'],
};
// metro.config.js - FIXED: Define defaultConfig trước khi sử dụng
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
/**
......@@ -6,6 +7,24 @@ const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
*
* @type {import('metro-config').MetroConfig}
*/
const config = {};
module.exports = mergeConfig(getDefaultConfig(__dirname), config);
// FIXME: Phải define defaultConfig TRƯỚC khi sử dụng trong config
const defaultConfig = getDefaultConfig(__dirname);
const config = {
// FEATURE: Cấu hình transformer để xử lý file SVG
transformer: {
babelTransformerPath: require.resolve('react-native-svg-transformer'),
},
// FEATURE: Cấu hình resolver để nhận diện file SVG
resolver: {
// NOTE: Loại bỏ 'svg' khỏi assetExts để không treat như asset
assetExts: defaultConfig.resolver.assetExts.filter(ext => ext !== 'svg'),
// NOTE: Thêm 'svg' vào sourceExts để treat như source code
sourceExts: [...defaultConfig.resolver.sourceExts, 'svg'],
},
};
module.exports = mergeConfig(defaultConfig, config);
\ No newline at end of file
......@@ -11,12 +11,12 @@
},
"dependencies": {
"@react-native-community/async-storage": "^1.12.1",
"@react-native-community/checkbox": "^0.5.9",
"@react-native-community/masked-view": "^0.1.11",
"@react-native-community/netinfo": "^7.1.7",
"@react-native-community/picker": "^1.8.1",
"@react-native-community/slider": "^4.1.12",
"@react-navigation/bottom-tabs": "^6.0.9",
"@react-navigation/drawer": "^6.x",
"@react-navigation/material-top-tabs": "^6.0.6",
"@react-navigation/native": "^6.0.6",
"@react-navigation/stack": "^6.0.11",
......@@ -49,7 +49,8 @@
"react-native-permissions": "^3.6.1",
"react-native-progress": "^5.0.0",
"react-native-qrcode-scanner": "^1.5.5",
"react-native-reanimated": "^3.12.1",
"react-native-reanimated-table": "^0.0.2",
"react-native-reanimated": "3.12.1",
"react-native-rename": "^2.9.0",
"react-native-render-html": "^6.1.0",
"react-native-responsive-fontsize": "^0.5.1",
......@@ -85,6 +86,7 @@
"eslint": "^8.19.0",
"jest": "^29.6.3",
"prettier": "2.8.8",
"react-native-svg-transformer": "^1.5.1",
"react-test-renderer": "18.2.0",
"typescript": "5.0.4"
},
......
......@@ -2,7 +2,7 @@ import React, {useEffect, useRef, useState} from 'react';
import StackNavigation from './routers/StackNavigation';
import {connect} from 'react-redux';
import DropdownAlert from 'react-native-dropdownalert';
import DropdownManager from './components/DropdownAlert/DropdownManager';
import DropdownManager from './components/Dropdown/DropdownAlert/DropdownManager';
import R from './assets/R';
import {HEIGHTXD, WIDTHXD} from './config/Functions';
import {SkypeIndicator} from 'react-native-indicators';
......
import { green } from "react-native-reanimated/lib/typescript/reanimated2/Colors";
const colors = {
main: '#00139B',
txtMain: '#006938',
label: '#5D5D5D',
color777: '#777777',
colorMainLight: '#5173B1',
colorBackground: '#E2E8F2',
borderGray: '#bbc2ce',
borderGraym: '#c9cfd9',
placeHolder: '#8D8D8D',
backgrPicker: '#E2E8F2',
dollar: '#07BA00',
colorBg: '#E8E8E8',
accent: '#A60014',
primary: '#0AC4BA',
secondary: '#00b33c',
black: '#000000',
white: '#FFFFFF',
orange: '#Fb9736',
lightBlue: '#1a8cff',
lightBlue1: '#008ae6',
lightBlue2: '#22AEFB',
rgbaBtn: '#79F8B5',
yellow: '#e6e600',
red: '#E3434F',
bgMain: '#9EF8C9',
colorButton1: '#43D75B',
colorTextLine: '#FFA412',
colorBgScreen: '#F7F8FA',
colorBgInputText: '#F2F2F2',
main: '#2F6BFF',
txtMain: '#000000',
shadowColor:'rgba(0, 0, 0, 0.25)',
label: 'rgba(75, 75, 75, 0.8)',
iconColorSel:'#2F6BFF',
iconColorUnSel:'#6C6C6C',
buttonColorUnSel:'#C4C4C4',
buttonColorSel:'rgba(47, 107, 255, 0.79)',
blue100:'rgba(47, 107, 255, 0.1)',
orange: '#F39A2B',
red:'#D60A0B',
textSubMain:'#2F6BFF',
backgroundInputSearch:'rgba(0, 0, 0, 0.13)',
grey:'rgba(204, 204, 204, 0.5)',
buttonHome:'rgba(217, 217, 217, 0.56)',
black:'#000000',
black_800:'rgba(22, 21, 28, 0.8)',
backgroundCard:'rgba(47, 107, 255, 0.1)',
grey_200:'rgba(162, 161, 168, 0.2)',
grey_50:'rgba(162, 161, 168, 0.05)',
grey_100:'rgba(162, 161, 168, 1)',
grey_800:'rgba(75, 75, 75, 0.8)',
yellow:'#F39A2B',
black_500:'rgba(0, 0, 0, 0.5)',
purple:'rgba(158, 183, 247, 1)',
// 🔵 Blue Shades
blue500: '#2F6BFF', // main, iconColorSel, textSubMain
blue400: 'rgba(47, 107, 255, 0.79)', // buttonColorSel
blue100: 'rgba(47, 107, 255, 0.1)', // blue100, backgroundCard
// ⚫ Black Shades
black900: '#000000', // txtMain, black
black800: 'rgba(22, 21, 28, 0.8)', // black_800
black500: 'rgba(0, 0, 0, 0.5)', // black_500
black250: 'rgba(0, 0, 0, 0.25)', // shadowColor
// ⚪ White
white: '#ffffff',
// ⚪ Gray Shades
gray280: 'rgba(204, 204, 204, 0.36)',
gray220: 'rgba(217, 217, 217, 0.56)',
gray800: 'rgba(75, 75, 75, 0.8)', // label, grey_800
gray600: '#6C6C6C', // iconColorUnSel
gray400: '#C4C4C4', // buttonColorUnSel
gray300: 'rgba(204, 204, 204, 0.5)', // grey
gray200: 'rgba(162, 161, 168, 1)', // grey_100
gray150: 'rgba(162, 161, 168, 0.2)', // grey_200
gray50: 'rgba(162, 161, 168, 0.05)', // grey_50
greyBlue_soft_50: 'rgba(221, 222, 238, 0.5)',
// 🟢 Green
green500: 'rgba(0, 255, 123, 1)', // green
green:'rgba(0, 255, 21, 1)',
// 🟠 Orange/Yellow
orange500: '#F39A2B', // orange, yellow (trùng mã)
// 🔴 Red
red500: '#D60A0B', // red
// 🟣 Purple
purple500: 'rgba(158, 183, 247, 1)', // purple
// 🔘 Background / UI
inputBackground: 'rgba(0, 0, 0, 0.13)', // backgroundInputSearch
buttonBackground: 'rgba(217, 217, 217, 0.56)', // buttonHome
};
export default colors;
const fonts = {
RobotoThin: 'Roboto-Thin',
RobotoThinItalic: 'Roboto-ThinItalic',
RobotoItalic: 'Roboto-Italic',
RobotoBlack: 'Roboto-Black',
RobotoBlackItalic: 'Roboto-BlackItalic',
RobotoBold: 'Roboto-Bold',
RobotoBoldItalic: 'Roboto-BoldItalic',
RobotoLight: 'Roboto-Light',
RobotoLightItalic: 'Roboto-LightItalic',
RobotoMedium: 'Roboto-Medium',
RobotoMediumItalic: 'Roboto-MediumItalic',
RobotoRegular: 'Roboto-Regular',
MontserratRegular: 'Montserrat-Regular',
MontserratMedium: 'Montserrat-Medium',
MontserratSemiBold: 'Montserrat-SemiBold',
MontserratItalic: 'Montserrat-Italic',
MontserratMediumItalic: 'Montserrat-MediumItalic',
MontserratSemiBoldItalic: 'Montserrat-SemiBoldItalic',
InterMedium:'Inter_18pt-Medium',
InterRegular:'Inter_18pt-Regular',
InterSemiBold:'Inter_18pt-SemiBold',
};
export default fonts;
const fontsize = {
fontSizeLabel: 14,
fontSizeContent: 14,
fontSizeInputText: 16,
fontsSize8:8,
fontsSize10:10,
fontsSize12: 12,
fontsSize14:14,
fontsSize16:16,
fontsSize18:18,
fontsSize20:20,
};
export default fontsize;
<svg width="12" height="6" viewBox="0 0 12 6" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 1L6 5L11 1" stroke="#16151C" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<svg width="13" height="22" viewBox="0 0 13 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.8686 12.207L2.37338 21.865L0 19.4509L8.3085 11L0 2.54907L2.37338 0.13501L11.8686 9.79298C12.1832 10.1131 12.36 10.5473 12.36 11C12.36 11.4527 12.1832 11.8869 11.8686 12.207Z" fill="black"/>
</svg>
<svg width="20" height="18" viewBox="0 0 20 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.67456 0.329502C10.1084 0.768849 10.1084 1.48115 9.67456 1.9205L3.79357 7.87501H18.8889C19.5026 7.87501 20 8.37868 20 9.00001C20 9.62135 19.5026 10.125 18.8889 10.125H3.79357L9.67456 16.0795C10.1084 16.5189 10.1084 17.2312 9.67456 17.6705C9.24067 18.1098 8.53711 18.1098 8.10322 17.6705L0.325433 9.7955C0.117067 9.58457 0 9.29836 0 9.00001C0 8.70166 0.117067 8.41546 0.325433 8.20453L8.10322 0.329502C8.53711 -0.109834 9.24067 -0.109834 9.67456 0.329502Z" fill="white"/>
</svg>
<svg width="20" height="18" viewBox="0 0 20 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.67456 0.329502C10.1084 0.768849 10.1084 1.48115 9.67456 1.9205L3.79357 7.87501H18.8889C19.5026 7.87501 20 8.37868 20 9.00001C20 9.62135 19.5026 10.125 18.8889 10.125H3.79357L9.67456 16.0795C10.1084 16.5189 10.1084 17.2312 9.67456 17.6705C9.24067 18.1098 8.53711 18.1098 8.10322 17.6705L0.325433 9.7955C0.117067 9.58457 0 9.29836 0 9.00001C0 8.70166 0.117067 8.41546 0.325433 8.20453L8.10322 0.329502C8.53711 -0.109834 9.24067 -0.109834 9.67456 0.329502Z" fill="black"/>
</svg>
<svg width="38" height="38" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.5 13.1667H36.5M9.27778 1.5V5.38889M28.7222 1.5V5.38889M7.33333 19H11.2222M17.0556 19H20.9444M26.7778 19H30.6667M7.33333 24.8333H11.2222M17.0556 24.8333H20.9444M26.7778 24.8333H30.6667M7.33333 30.6667H11.2222M17.0556 30.6667H20.9444M26.7778 30.6667H30.6667M7.72222 36.5H30.2778C32.4557 36.5 33.5448 36.5 34.3767 36.0761C35.1084 35.7034 35.7034 35.1084 36.0761 34.3767C36.5 33.5448 36.5 32.4557 36.5 30.2778V11.6111C36.5 9.43312 36.5 8.34413 36.0761 7.51226C35.7034 6.78051 35.1084 6.18559 34.3767 5.81276C33.5448 5.38889 32.4557 5.38889 30.2778 5.38889H7.72222C5.54425 5.38889 4.45524 5.38889 3.62337 5.81276C2.89162 6.18559 2.2967 6.78051 1.92387 7.51226C1.5 8.34413 1.5 9.43312 1.5 11.6111V30.2778C1.5 32.4557 1.5 33.5448 1.92387 34.3767C2.2967 35.1084 2.89162 35.7034 3.62337 36.0761C4.45524 36.5 5.54423 36.5 7.72222 36.5Z" stroke="#2F6BFF" stroke-width="2" stroke-linecap="round"/>
</svg>
<svg width="26" height="29" viewBox="0 0 26 29" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15.9964 16.4115C15.9964 18.3275 14.5748 19.8807 12.8212 19.8807C11.0676 19.8807 9.646 18.3275 9.646 16.4115C9.646 14.4955 11.0676 12.9423 12.8212 12.9423C14.5748 12.9423 15.9964 14.4955 15.9964 16.4115Z" stroke="#16151C" stroke-width="1.5"/>
<ellipse cx="12.8216" cy="8.89493" rx="1.0584" ry="1.1564" fill="#16151C"/>
<path d="M22.3471 18.7243V14.0987C22.3471 10.9054 19.9778 8.31672 17.0551 8.31672H16.9217C16.4517 6.32167 14.7942 4.84752 12.8215 4.84752C10.8488 4.84752 9.19125 6.32167 8.72128 8.31672H8.5879C5.66521 8.31672 3.2959 10.9054 3.2959 14.0987V18.7243C3.2959 21.9176 5.66521 24.5063 8.5879 24.5063H17.0551C19.9778 24.5063 22.3471 21.9176 22.3471 18.7243Z" stroke="#16151C" stroke-width="1.5" stroke-linejoin="round"/>
</svg>
<svg width="38" height="38" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.5 13.1667H36.5M9.27778 1.5V5.38889M28.7222 1.5V5.38889M7.33333 19H11.2222M17.0556 19H20.9444M26.7778 19H30.6667M7.33333 24.8333H11.2222M17.0556 24.8333H20.9444M26.7778 24.8333H30.6667M7.33333 30.6667H11.2222M17.0556 30.6667H20.9444M26.7778 30.6667H30.6667M7.72222 36.5H30.2778C32.4557 36.5 33.5448 36.5 34.3767 36.0761C35.1084 35.7034 35.7034 35.1084 36.0761 34.3767C36.5 33.5448 36.5 32.4557 36.5 30.2778V11.6111C36.5 9.43312 36.5 8.34413 36.0761 7.51226C35.7034 6.78051 35.1084 6.18559 34.3767 5.81276C33.5448 5.38889 32.4557 5.38889 30.2778 5.38889H7.72222C5.54425 5.38889 4.45524 5.38889 3.62337 5.81276C2.89162 6.18559 2.2967 6.78051 1.92387 7.51226C1.5 8.34413 1.5 9.43312 1.5 11.6111V30.2778C1.5 32.4557 1.5 33.5448 1.92387 34.3767C2.2967 35.1084 2.89162 35.7034 3.62337 36.0761C4.45524 36.5 5.54423 36.5 7.72222 36.5Z" stroke="none" stroke-width="2" stroke-linecap="round"/>
</svg>
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7 1.5V18.5M18.5 7.5H1.5M1 7.4C1 5.16 1 4.04 1.436 3.184C1.81949 2.43139 2.43139 1.81949 3.184 1.436C4.04 1 5.16 1 7.4 1H12.6C14.84 1 15.96 1 16.816 1.436C17.5686 1.81949 18.1805 2.43139 18.564 3.184C19 4.04 19 5.16 19 7.4V12.6C19 14.84 19 15.96 18.564 16.816C18.1805 17.5686 17.5686 18.1805 16.816 18.564C15.96 19 14.84 19 12.6 19H7.4C5.16 19 4.04 19 3.184 18.564C2.43139 18.1805 1.81949 17.5686 1.436 16.816C1 15.96 1 14.84 1 12.6V7.4Z" stroke="none" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<svg width="38" height="38" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.25 4.19231V1.5" stroke="#2F6BFF" stroke-width="2.5" stroke-linecap="round"/>
<path d="M27.75 4.19231V1.5" stroke="#2F6BFF" stroke-width="2.5" stroke-linecap="round"/>
<path d="M13.75 23.0384L16.375 20.3461V27.5256" stroke="#2F6BFF" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M20.75 25.7307V22.141C20.75 21.1497 21.5335 20.3461 22.5 20.3461C23.4665 20.3461 24.25 21.1497 24.25 22.141V25.7307C24.25 26.7221 23.4665 27.5256 22.5 27.5256C21.5335 27.5256 20.75 26.7221 20.75 25.7307Z" stroke="#2F6BFF" stroke-width="2.5" stroke-linecap="round"/>
<path d="M35.625 13.1667H27.0938H16.8125M1.5 13.1667H8.28125" stroke="#2F6BFF" stroke-width="2.5" stroke-linecap="round"/>
<path d="M22.5 36.5H15.5C8.90033 36.5 5.60051 36.5 3.55025 34.3971C1.5 32.2944 1.5 28.9098 1.5 22.141V18.5513C1.5 11.7824 1.5 8.39794 3.55025 6.29511C5.60051 4.19229 8.90033 4.19229 15.5 4.19229H22.5C29.0996 4.19229 32.3996 4.19229 34.4497 6.29511C36.5 8.39794 36.5 11.7824 36.5 18.5513V22.141C36.5 28.9098 36.5 32.2944 34.4497 34.3971C33.3066 35.5695 31.7752 36.0882 29.5 36.3178" stroke="#2F6BFF" stroke-width="2.5" stroke-linecap="round"/>
</svg>
<svg width="20" height="19" viewBox="0 0 20 19" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2 5.5H18V2.5H2V5.5ZM12 16.5V7.5H8V16.5H12ZM14 16.5H18V7.5H14V16.5ZM6 16.5V7.5H2V16.5H6ZM1 0.5H19C19.2652 0.5 19.5196 0.605357 19.7071 0.792893C19.8946 0.98043 20 1.23478 20 1.5V17.5C20 17.7652 19.8946 18.0196 19.7071 18.2071C19.5196 18.3946 19.2652 18.5 19 18.5H1C0.734784 18.5 0.48043 18.3946 0.292893 18.2071C0.105357 18.0196 0 17.7652 0 17.5V1.5C0 1.23478 0.105357 0.98043 0.292893 0.792893C0.48043 0.605357 0.734784 0.5 1 0.5Z" fill="black"/>
</svg>
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 20H20V0H0V20ZM2 18V13H6V18H2ZM8 18V13H12V18H8ZM14 18V13H18V18H14ZM18 11H14V6H18V11ZM18 4H2V2H18V4ZM2 6H6V11H2V6ZM8 11V6H12V11H8Z" fill="black"/>
</svg>
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19 20H1C0.734784 20 0.48043 19.8946 0.292893 19.7071C0.105357 19.5196 0 19.2652 0 19V1C0 0.734784 0.105357 0.48043 0.292893 0.292893C0.48043 0.105357 0.734784 0 1 0H19C19.2652 0 19.5196 0.105357 19.7071 0.292893C19.8946 0.48043 20 0.734784 20 1V19C20 19.2652 19.8946 19.5196 19.7071 19.7071C19.5196 19.8946 19.2652 20 19 20ZM2 18H18V2H2V18Z" fill="black"/>
<path d="M7 20C6.73478 20 6.48043 19.8946 6.29289 19.7071C6.10536 19.5196 6 19.2652 6 19V1C6 0.734784 6.10536 0.48043 6.29289 0.292893C6.48043 0.105357 6.73478 0 7 0C7.26522 0 7.51957 0.105357 7.70711 0.292893C7.89464 0.48043 8 0.734784 8 1V19C8 19.2652 7.89464 19.5196 7.70711 19.7071C7.51957 19.8946 7.26522 20 7 20ZM13 20C12.7348 20 12.4804 19.8946 12.2929 19.7071C12.1054 19.5196 12 19.2652 12 19V1C12 0.734784 12.1054 0.48043 12.2929 0.292893C12.4804 0.105357 12.7348 0 13 0C13.2652 0 13.5196 0.105357 13.7071 0.292893C13.8946 0.48043 14 0.734784 14 1V19C14 19.2652 13.8946 19.5196 13.7071 19.7071C13.5196 19.8946 13.2652 20 13 20Z" fill="black"/>
<path d="M19 8H1C0.734784 8 0.48043 7.89464 0.292893 7.70711C0.105357 7.51957 0 7.26522 0 7C0 6.73478 0.105357 6.48043 0.292893 6.29289C0.48043 6.10536 0.734784 6 1 6H19C19.2652 6 19.5196 6.10536 19.7071 6.29289C19.8946 6.48043 20 6.73478 20 7C20 7.26522 19.8946 7.51957 19.7071 7.70711C19.5196 7.89464 19.2652 8 19 8ZM19 14H1C0.734784 14 0.48043 13.8946 0.292893 13.7071C0.105357 13.5196 0 13.2652 0 13C0 12.7348 0.105357 12.4804 0.292893 12.2929C0.48043 12.1054 0.734784 12 1 12H19C19.2652 12 19.5196 12.1054 19.7071 12.2929C19.8946 12.4804 20 12.7348 20 13C20 13.2652 19.8946 13.5196 19.7071 13.7071C19.5196 13.8946 19.2652 14 19 14Z" fill="black"/>
</svg>
<svg width="10" height="10" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.66333 7.14474H11.6633M6.66333 1.8158V12.4737" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.5 6.25C4.81 6.25 4.25 5.69 4.25 5C4.25 4.31 4.81 3.75 5.5 3.75C6.19 3.75 6.75 4.31 6.75 5C6.75 5.69 6.19 6.25 5.5 6.25ZM5.5 2.5C4.11937 2.5 3 3.61937 3 5C3 6.38063 4.11937 7.5 5.5 7.5C6.88063 7.5 8 6.38063 8 5C8 3.61937 6.88063 2.5 5.5 2.5ZM19.25 10.705L15.5 6.875L9.28687 13.1944L6.75 10.625L1.75 15.2106V2.5C1.75 1.81 2.31 1.25 3 1.25H18C18.69 1.25 19.25 1.81 19.25 2.5V10.705ZM19.25 17.5C19.25 18.19 18.69 18.75 18 18.75H14.77L10.165 14.0844L15.5 8.74938L19.25 12.4994V17.5ZM3 18.75C2.31 18.75 1.75 18.19 1.75 17.5V16.9131L6.71563 12.4656L13.0006 18.75H3ZM18 0H3C1.61937 0 0.5 1.11937 0.5 2.5V17.5C0.5 18.8806 1.61937 20 3 20H18C19.3806 20 20.5 18.8806 20.5 17.5V2.5C20.5 1.11937 19.3806 0 18 0Z" fill="#2F6BFF"/>
</svg>
<svg width="38" height="37" viewBox="0 0 38 37" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M28.7222 16.5556H9.27777M24.8333 16.5556V20.4444M26.7778 8.77778H11.2222V2.94444C11.2222 2.42875 11.4271 1.93417 11.7917 1.56951C12.1564 1.20486 12.651 1 13.1667 1H24.8333C25.349 1 25.8436 1.20486 26.2083 1.56951C26.5729 1.93417 26.7778 2.42875 26.7778 2.94444V8.77778Z" stroke="#2F6BFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M36.5 34.0555V10.7222C36.5 9.64833 35.6294 8.77777 34.5556 8.77777L3.44445 8.77777C2.37056 8.77777 1.5 9.64833 1.5 10.7222V34.0555C1.5 35.1294 2.37056 36 3.44445 36H34.5556C35.6294 36 36.5 35.1294 36.5 34.0555Z" stroke="#2F6BFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<svg width="36" height="35" viewBox="0 0 36 35" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.9999 17.093C18.6742 17.093 19.2209 17.6397 19.2209 18.3139V19.5349H20.4418C21.1161 19.5349 21.6627 20.0815 21.6627 20.7558C21.6627 21.4301 21.1161 21.9767 20.4418 21.9767H19.2209V23.1977C19.2209 23.8719 18.6742 24.4186 17.9999 24.4186C17.3257 24.4186 16.779 23.8719 16.779 23.1977V21.9767H15.5581C14.8838 21.9767 14.3372 21.4301 14.3372 20.7558C14.3372 20.0815 14.8838 19.5349 15.5581 19.5349H16.779V18.3139C16.779 17.6397 17.3257 17.093 17.9999 17.093Z" fill="#2F6BFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M18 13.0233C13.7294 13.0233 10.2675 16.4853 10.2675 20.7558C10.2675 25.0265 13.7294 28.4884 18 28.4884C22.2707 28.4884 25.7326 25.0265 25.7326 20.7558C25.7326 16.4853 22.2707 13.0233 18 13.0233ZM12.7093 20.7558C12.7093 17.8339 15.0781 15.4651 18 15.4651C20.9219 15.4651 23.2907 17.8339 23.2907 20.7558C23.2907 23.6777 20.9219 26.0465 18 26.0465C15.0781 26.0465 12.7093 23.6777 12.7093 20.7558Z" fill="#2F6BFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.9153 1.87354e-06C16.4527 -4.69637e-05 15.233 -7.94682e-05 14.2648 0.130088C13.2428 0.2675 12.3201 0.569753 11.5787 1.31122C10.8372 2.05268 10.5349 2.97538 10.3975 3.99736C10.3013 4.71299 10.2762 5.56596 10.2697 6.55286C9.21399 6.58674 8.27285 6.64847 7.43648 6.76093C5.52789 7.01753 3.98309 7.55818 2.76481 8.77646C1.54655 9.99472 1.00589 11.5395 0.749298 13.4481C0.499952 15.3027 0.499968 17.6722 0.500001 20.664V20.8476C0.499968 23.8394 0.499952 26.209 0.749298 28.0635C1.00589 29.9721 1.54655 31.5169 2.76481 32.7353C3.98309 33.9534 5.52789 34.4941 7.43648 34.7508C9.29099 35 11.6606 35 14.6523 35H21.3476C24.3394 35 26.709 35 28.5635 34.7508C30.472 34.4941 32.0169 33.9534 33.2353 32.7353C34.4534 31.5169 34.994 29.9721 35.2508 28.0635C35.5 26.209 35.5 23.8394 35.5 20.8478V20.664C35.5 17.6724 35.5 15.3027 35.2508 13.4481C34.994 11.5395 34.4534 9.99472 33.2353 8.77646C32.0169 7.55818 30.472 7.01753 28.5635 6.76093C27.7271 6.64847 26.786 6.58674 25.7303 6.55286C25.7238 5.56596 25.6987 4.71299 25.6025 3.99736C25.4651 2.97538 25.1628 2.05268 24.4213 1.31122C23.6799 0.569753 22.7572 0.2675 21.7352 0.130088C20.767 -7.94682e-05 19.5473 -4.69637e-05 18.0847 1.87354e-06H17.9153ZM23.2878 6.51453C23.2809 5.5861 23.2581 4.88576 23.1824 4.32275C23.0813 3.57152 22.9068 3.25002 22.6947 3.03787C22.4826 2.82572 22.1611 2.65118 21.4098 2.55018C20.6235 2.44447 19.5693 2.44186 18 2.44186C16.4307 2.44186 15.3765 2.44447 14.5902 2.55018C13.839 2.65118 13.5174 2.82572 13.3053 3.03787C13.0932 3.25002 12.9186 3.57152 12.8176 4.32275C12.7419 4.88576 12.7191 5.5861 12.7122 6.51453C13.3278 6.51163 13.9741 6.51163 14.6523 6.51163H21.3476C22.026 6.51163 22.6723 6.51163 23.2878 6.51453ZM4.49147 10.5031C5.18041 9.81417 6.12403 9.40121 7.76185 9.18101C9.43478 8.95609 11.6401 8.95349 14.7442 8.95349H21.2558C24.3599 8.95349 26.5652 8.95609 28.2382 9.18101C29.8759 9.40121 30.8196 9.81417 31.5085 10.5031C32.1975 11.1921 32.6105 12.1357 32.8306 13.7735C33.0555 15.4464 33.0581 17.6517 33.0581 20.7558C33.0581 23.8599 33.0555 26.0652 32.8306 27.7382C32.6105 29.3759 32.1975 30.3196 31.5085 31.0085C30.8196 31.6975 29.8759 32.1105 28.2382 32.3306C26.5652 32.5555 24.3599 32.5581 21.2558 32.5581H14.7442C11.6401 32.5581 9.43478 32.5555 7.76185 32.3306C6.12403 32.1105 5.18041 31.6975 4.49147 31.0085C3.80252 30.3196 3.38958 29.3759 3.16938 27.7382C2.94445 26.0652 2.94186 23.8599 2.94186 20.7558C2.94186 17.6517 2.94445 15.4464 3.16938 13.7735C3.38958 12.1357 3.80252 11.1921 4.49147 10.5031Z" fill="#2F6BFF"/>
</svg>
<svg width="23" height="16" viewBox="0 0 23 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 8.00098H22" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1 14.2998H22" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1 1.7002H22" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<svg width="21" height="23" viewBox="0 0 21 23" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.2491 9.20957V8.50497C17.2491 4.63623 14.2274 1.5 10.5 1.5C6.77256 1.5 3.75087 4.63623 3.75087 8.50497V9.20957C3.75087 10.0552 3.50972 10.8818 3.0578 11.5854L1.95036 13.3095C0.938821 14.8843 1.71105 17.0249 3.47036 17.5229C8.07274 18.8257 12.9273 18.8257 17.5296 17.5229C19.289 17.0249 20.0612 14.8843 19.0496 13.3095L17.9422 11.5854C17.4903 10.8818 17.2491 10.0552 17.2491 9.20957Z" stroke="#6C6C6C" stroke-width="1.5"/>
<path d="M6 18.5C6.65503 20.2478 8.42246 21.5 10.5 21.5C12.5775 21.5 14.345 20.2478 15 18.5" stroke="#6C6C6C" stroke-width="1.5" stroke-linecap="round"/>
</svg>
<svg width="46" height="35" viewBox="0 0 46 35" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.7184 4.75186C13.6079 4.75186 15.1452 6.28916 15.1452 8.17873C15.1452 10.0683 13.6079 11.6056 11.7184 11.6056C10.3638 11.6056 9.13381 10.8043 8.58483 9.56409L7.73706 9.93935C8.43446 11.5147 9.99716 12.5326 11.7184 12.5326C14.1191 12.5326 16.0722 10.5795 16.0722 8.17873C16.0722 5.77799 14.1191 3.82483 11.7184 3.82483C9.31857 3.82483 7.36615 5.77799 7.36615 8.17873H8.29318C8.29318 6.28916 9.82974 4.75186 11.7184 4.75186Z" fill="#2F6BFF"/>
<path d="M16.0323 28.0702L16.6114 28.7943C16.9178 28.5491 17.2085 28.2787 17.4755 27.9905L16.7953 27.3606C16.5596 27.6151 16.3029 27.8539 16.0323 28.0702Z" fill="#2F6BFF"/>
<path d="M3.80524 22.6106L4.73227 22.6124C4.73292 22.2648 4.75971 21.9151 4.81199 21.573L3.89553 21.4332C3.83639 21.8208 3.80607 22.217 3.80524 22.6106Z" fill="#2F6BFF"/>
<path d="M19.5665 22.249C19.5533 21.9777 19.5259 21.705 19.4854 21.4382L18.5688 21.5776C18.6047 21.8132 18.6287 22.0545 18.6405 22.2942C18.6457 22.4013 18.6486 22.51 18.6489 22.6174L19.5759 22.6145C19.5756 22.493 19.5724 22.3702 19.5665 22.249Z" fill="#2F6BFF"/>
<path d="M14.5739 29.9734C14.9393 29.8298 15.2972 29.6572 15.6376 29.4602L15.173 28.6579C14.873 28.8317 14.5573 28.984 14.2352 29.1105L14.5739 29.9734Z" fill="#2F6BFF"/>
<path d="M11.0982 30.4955L11.1667 29.571C10.8207 29.5453 10.4743 29.4933 10.1369 29.4162L9.93048 30.3201C10.3132 30.4073 10.7059 30.4663 11.0982 30.4955Z" fill="#2F6BFF"/>
<path d="M18.801 26.0448L17.9655 25.643C17.8154 25.9551 17.6402 26.2589 17.4448 26.5457L18.211 27.0676C18.4324 26.7427 18.6309 26.3984 18.801 26.0448Z" fill="#2F6BFF"/>
<path d="M19.4915 23.7913L18.5744 23.6561C18.5238 23.9992 18.4466 24.3412 18.345 24.6724L19.2313 24.9442C19.3465 24.5685 19.434 24.1806 19.4915 23.7913Z" fill="#2F6BFF"/>
<path d="M12.278 30.4957C12.6708 30.4666 13.0635 30.4078 13.445 30.3212L13.2397 29.4171C12.9031 29.4936 12.5562 29.5455 12.2092 29.5712L12.278 30.4957Z" fill="#2F6BFF"/>
<path d="M5.03506 24.6685C4.9342 24.3379 4.85744 23.996 4.80692 23.6523L3.88971 23.7871C3.94691 24.1765 4.03396 24.5641 4.14835 24.939L5.03506 24.6685Z" fill="#2F6BFF"/>
<path d="M6.60984 17.878L5.93283 17.2447C5.66445 17.5316 5.41545 17.8409 5.19287 18.1642L5.95628 18.69C6.153 18.4046 6.3728 18.1314 6.60984 17.878Z" fill="#2F6BFF"/>
<path d="M7.73865 29.4566C8.07887 29.6539 8.43661 29.827 8.80177 29.9711L9.1418 29.1087C8.81966 28.9816 8.5041 28.8289 8.20383 28.6548L7.73865 29.4566Z" fill="#2F6BFF"/>
<path d="M5.9325 26.5406C5.73754 26.254 5.5628 25.9505 5.41327 25.6385L4.57727 26.0394C4.74692 26.3931 4.94493 26.7372 5.16603 27.0621L5.9325 26.5406Z" fill="#2F6BFF"/>
<path d="M4.16162 20.2817L5.04647 20.558C5.14974 20.2276 5.27907 19.9018 5.43101 19.5898L4.5976 19.1839C4.42536 19.5376 4.27871 19.9069 4.16162 20.2817Z" fill="#2F6BFF"/>
<path d="M16.7759 17.8826C17.013 18.1361 17.2326 18.4094 17.4288 18.6946L18.1927 18.1693C17.9704 17.8461 17.7215 17.5366 17.453 17.2495L16.7759 17.8826Z" fill="#2F6BFF"/>
<path d="M6.76472 28.7894L7.34402 28.0656C7.07324 27.8489 6.81663 27.6101 6.58126 27.3557L5.90082 27.9854C6.16743 28.2735 6.45806 28.544 6.76472 28.7894Z" fill="#2F6BFF"/>
<path d="M19.2212 20.2872C19.1047 19.9121 18.9586 19.5427 18.7869 19.1893L17.953 19.5943C18.1044 19.9058 18.2332 20.2315 18.3359 20.5621L19.2212 20.2872Z" fill="#2F6BFF"/>
<path d="M35.2368 34.06H1.42703V3.60052H4.90878C3.99204 4.93119 3.45445 6.54227 3.45445 8.27684C3.45445 10.4164 5.22379 13.5337 7.09074 16.2274C6.99275 16.2979 6.8955 16.3708 6.80141 16.4452L7.37663 17.1722C7.45756 17.1081 7.54164 17.046 7.62591 16.9852C8.24693 17.8486 8.861 18.6505 9.4072 19.3397C8.30969 20.0963 7.6401 21.3507 7.6401 22.6977C7.6401 24.9468 9.46987 26.7766 11.719 26.7766C13.9682 26.7766 15.798 24.9468 15.798 22.6977C15.798 21.3502 15.1283 20.0957 14.0305 19.3391C14.5711 18.6571 15.1782 17.8649 15.7926 17.0117C15.866 17.0653 15.9383 17.1201 16.0093 17.1763L16.5849 16.4497C16.5009 16.383 16.4149 16.3183 16.3279 16.255C18.2021 13.555 19.9839 10.4237 19.9839 8.27684C19.9839 6.54237 19.4462 4.93128 18.5294 3.60052H24.2671V2.67349H17.7879C16.2767 1.03858 14.1153 0.0130005 11.7185 0.0130005C9.3221 0.0130005 7.1611 1.03858 5.65031 2.67349H0.5V34.9871H35.2368V34.06ZM14.8709 22.6975C14.8709 24.4355 13.4569 25.8494 11.7189 25.8494C9.98094 25.8494 8.56703 24.4355 8.56703 22.6975C8.56703 21.6337 9.10657 20.6435 9.98845 20.0633C10.1015 20.2021 10.2091 20.3331 10.3115 20.457C9.58297 20.9296 9.129 21.7466 9.129 22.6313C9.129 24.0593 10.2908 25.2211 11.7189 25.2211C13.1472 25.2211 14.3094 24.0594 14.3094 22.6313C14.3094 21.7462 13.8549 20.9289 13.1255 20.4565C13.2281 20.3325 13.3357 20.2014 13.4488 20.0627C14.3311 20.6427 14.8709 21.6332 14.8709 22.6975ZM12.5226 21.1752C13.0488 21.466 13.3824 22.0237 13.3824 22.6314C13.3824 23.5483 12.6362 24.2942 11.7189 24.2942C10.8021 24.2942 10.0561 23.5483 10.0561 22.6314C10.0561 22.0242 10.3892 21.4668 10.9146 21.1758C11.1662 21.4711 11.3296 21.6565 11.3712 21.7035L11.7182 22.0956L12.0653 21.7035C12.1071 21.6564 12.2706 21.4707 12.5226 21.1752ZM11.7183 0.93994C15.7647 0.93994 19.0568 4.23118 19.0568 8.27675C19.0568 11.8536 13.2177 18.9295 11.7183 20.6872C10.2187 18.9292 4.38148 11.8549 4.38148 8.27675C4.38148 4.23128 7.67282 0.93994 11.7183 0.93994Z" fill="#2F6BFF"/>
<path d="M28.7167 3.60068H44.573V34.0603H36.9463V34.9873H45.5V2.67365H28.7167V3.60068Z" fill="#2F6BFF"/>
<path d="M27.2951 2.67365H25.7028V3.60068H27.2951V2.67365Z" fill="#2F6BFF"/>
<path d="M21.5406 28.9374L25.8386 24.2273H42.2788V9.45575H21.5406V28.9374ZM22.4677 10.3828H41.3518V23.3003H25.4294L22.4677 26.5462V10.3828Z" fill="#2F6BFF"/>
<path d="M38.6314 13.8314H27.357V14.7585H38.6314V13.8314Z" fill="#2F6BFF"/>
<path d="M26.3409 13.8314H25.1886V14.7585H26.3409V13.8314Z" fill="#2F6BFF"/>
<path d="M34.5985 19.1265H25.1886V20.0535H34.5985V19.1265Z" fill="#2F6BFF"/>
<path d="M38.6313 16.4789H36.767V17.4059H38.6313V16.4789Z" fill="#2F6BFF"/>
<path d="M35.8067 16.4789H25.1886V17.4059H35.8067V16.4789Z" fill="#2F6BFF"/>
</svg>
<svg width="20" height="23" viewBox="0 0 20 23" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10 9.92857C12.7614 9.92857 15 7.81791 15 5.21429C15 2.61066 12.7614 0.5 10 0.5C7.23858 0.5 5 2.61066 5 5.21429C5 7.81791 7.23858 9.92857 10 9.92857Z" fill="#4B4B4B" fill-opacity="0.8"/>
<path d="M20 17.7857C20 15.182 17.7615 13.0714 15 13.0714H5C2.23858 13.0714 0 15.182 0 17.7857V22.5H20V17.7857Z" fill="#4B4B4B" fill-opacity="0.8"/>
</svg>
<svg width="36" height="35" viewBox="0 0 36 35" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M25.2917 7C25.1306 7 25 7.13058 25 7.29167V10.2083C25 10.3694 25.1306 10.5 25.2917 10.5H28.2083C28.3694 10.5 28.5 10.3694 28.5 10.2083V7.29167C28.5 7.13058 28.3694 7 28.2083 7H25.2917ZM25 28V27.125C25 26.6418 25.3918 26.25 25.875 26.25C26.3582 26.25 26.75 26.6418 26.75 27.125V28H28.5V27.125C28.5 26.6418 28.8918 26.25 29.375 26.25C29.8582 26.25 30.25 26.6418 30.25 27.125V28.875C30.25 29.3582 29.8582 29.75 29.375 29.75H22.375C21.8918 29.75 21.5 29.3582 21.5 28.875V27.125C21.5 26.6418 21.8918 26.25 22.375 26.25C22.8582 26.25 23.25 26.6418 23.25 27.125V28H25ZM19.75 15.75H20.625C21.1082 15.75 21.5 16.1418 21.5 16.625C21.5 17.1082 21.1082 17.5 20.625 17.5H17.125C16.6418 17.5 16.25 17.1082 16.25 16.625C16.25 16.1418 16.6418 15.75 17.125 15.75H18V14H15.375C14.8918 14 14.5 13.6082 14.5 13.125C14.5 12.6418 14.8918 12.25 15.375 12.25H20.625C21.1082 12.25 21.5 12.6418 21.5 13.125C21.5 13.6082 21.1082 14 20.625 14H19.75V15.75ZM28.5 17.5H27.625C27.1418 17.5 26.75 17.1082 26.75 16.625C26.75 16.1418 27.1418 15.75 27.625 15.75H28.5V14.875C28.5 14.3918 28.8918 14 29.375 14C29.8582 14 30.25 14.3918 30.25 14.875V18.375C30.25 18.8582 29.8582 19.25 29.375 19.25C28.8918 19.25 28.5 18.8582 28.5 18.375V17.5ZM19.75 21H18.875C18.3918 21 18 20.6082 18 20.125C18 19.6418 18.3918 19.25 18.875 19.25H20.625C21.1082 19.25 21.5 19.6418 21.5 20.125V23.625C21.5 24.1082 21.1082 24.5 20.625 24.5H15.375C14.8918 24.5 14.5 24.1082 14.5 23.625C14.5 23.1418 14.8918 22.75 15.375 22.75H19.75V21ZM25.2917 5.25H28.2083C29.3359 5.25 30.25 6.16408 30.25 7.29167V10.2083C30.25 11.3359 29.3359 12.25 28.2083 12.25H25.2917C24.1641 12.25 23.25 11.3359 23.25 10.2083V7.29167C23.25 6.16408 24.1641 5.25 25.2917 5.25ZM7.79167 5.25H10.7083C11.8359 5.25 12.75 6.16408 12.75 7.29167V10.2083C12.75 11.3359 11.8359 12.25 10.7083 12.25H7.79167C6.66408 12.25 5.75 11.3359 5.75 10.2083V7.29167C5.75 6.16408 6.66408 5.25 7.79167 5.25ZM7.79167 7C7.63058 7 7.5 7.13058 7.5 7.29167V10.2083C7.5 10.3694 7.63058 10.5 7.79167 10.5H10.7083C10.8694 10.5 11 10.3694 11 10.2083V7.29167C11 7.13058 10.8694 7 10.7083 7H7.79167ZM7.79167 22.75H10.7083C11.8359 22.75 12.75 23.6641 12.75 24.7917V27.7083C12.75 28.8359 11.8359 29.75 10.7083 29.75H7.79167C6.66408 29.75 5.75 28.8359 5.75 27.7083V24.7917C5.75 23.6641 6.66408 22.75 7.79167 22.75ZM7.79167 24.5C7.63058 24.5 7.5 24.6306 7.5 24.7917V27.7083C7.5 27.8694 7.63058 28 7.79167 28H10.7083C10.8694 28 11 27.8694 11 27.7083V24.7917C11 24.6306 10.8694 24.5 10.7083 24.5H7.79167ZM19.75 7H15.375C14.8918 7 14.5 6.60825 14.5 6.125C14.5 5.64175 14.8918 5.25 15.375 5.25H20.625C21.1082 5.25 21.5 5.64175 21.5 6.125V9.625C21.5 10.1082 21.1082 10.5 20.625 10.5C20.1418 10.5 19.75 10.1082 19.75 9.625V7ZM15.375 10.5C14.8918 10.5 14.5 10.1082 14.5 9.625C14.5 9.14175 14.8918 8.75 15.375 8.75H17.125C17.6082 8.75 18 9.14175 18 9.625C18 10.1082 17.6082 10.5 17.125 10.5H15.375ZM6.625 21C6.14175 21 5.75 20.6082 5.75 20.125C5.75 19.6418 6.14175 19.25 6.625 19.25H10.125C10.6082 19.25 11 19.6418 11 20.125C11 20.6082 10.6082 21 10.125 21H6.625ZM13.625 21C13.1418 21 12.75 20.6082 12.75 20.125C12.75 19.6418 13.1418 19.25 13.625 19.25H15.375C15.8582 19.25 16.25 19.6418 16.25 20.125C16.25 20.6082 15.8582 21 15.375 21H13.625ZM16.25 28V28.875C16.25 29.3582 15.8582 29.75 15.375 29.75C14.8918 29.75 14.5 29.3582 14.5 28.875V27.125C14.5 26.6418 14.8918 26.25 15.375 26.25H18.875C19.3582 26.25 19.75 26.6418 19.75 27.125C19.75 27.6082 19.3582 28 18.875 28H16.25ZM12.75 15.75H13.625C14.1082 15.75 14.5 16.1418 14.5 16.625C14.5 17.1082 14.1082 17.5 13.625 17.5H11.875C11.3918 17.5 11 17.1082 11 16.625V15.75H10.125C9.64175 15.75 9.25 15.3582 9.25 14.875C9.25 14.3918 9.64175 14 10.125 14H11.875C12.3582 14 12.75 14.3918 12.75 14.875V15.75ZM5.75 14.875C5.75 14.3918 6.14175 14 6.625 14C7.10825 14 7.5 14.3918 7.5 14.875V16.625C7.5 17.1082 7.10825 17.5 6.625 17.5C6.14175 17.5 5.75 17.1082 5.75 16.625V14.875ZM23.25 14.875C23.25 14.3918 23.6418 14 24.125 14C24.6082 14 25 14.3918 25 14.875V18.375C25 18.8582 24.6082 19.25 24.125 19.25C23.6418 19.25 23.25 18.8582 23.25 18.375V14.875ZM26.75 22.75V21.875C26.75 21.3918 27.1418 21 27.625 21H29.375C29.8582 21 30.25 21.3918 30.25 21.875C30.25 22.3582 29.8582 22.75 29.375 22.75H28.5V23.625C28.5 24.1082 28.1082 24.5 27.625 24.5H24.125C23.6418 24.5 23.25 24.1082 23.25 23.625V21.875C23.25 21.3918 23.6418 21 24.125 21C24.6082 21 25 21.3918 25 21.875V22.75H26.75ZM2.25 7.875C2.25 8.35825 1.85825 8.75 1.375 8.75C0.891751 8.75 0.5 8.35825 0.5 7.875V4.375C0.5 1.95875 2.45875 0 4.875 0H8.375C8.85825 0 9.25 0.391751 9.25 0.875C9.25 1.35825 8.85825 1.75 8.375 1.75H4.875C3.42525 1.75 2.25 2.92525 2.25 4.375V7.875ZM27.625 1.75C27.1418 1.75 26.75 1.35825 26.75 0.875C26.75 0.391751 27.1418 0 27.625 0H31.125C33.5412 0 35.5 1.95875 35.5 4.375V7.875C35.5 8.35825 35.1082 8.75 34.625 8.75C34.1418 8.75 33.75 8.35825 33.75 7.875V4.375C33.75 2.92525 32.5747 1.75 31.125 1.75H27.625ZM8.375 33.25C8.85825 33.25 9.25 33.6418 9.25 34.125C9.25 34.6082 8.85825 35 8.375 35H4.875C2.45875 35 0.5 33.0412 0.5 30.625V27.125C0.5 26.6418 0.891751 26.25 1.375 26.25C1.85825 26.25 2.25 26.6418 2.25 27.125V30.625C2.25 32.0747 3.42525 33.25 4.875 33.25H8.375ZM33.75 27.125C33.75 26.6418 34.1418 26.25 34.625 26.25C35.1082 26.25 35.5 26.6418 35.5 27.125V30.625C35.5 33.0412 33.5412 35 31.125 35H27.625C27.1418 35 26.75 34.6082 26.75 34.125C26.75 33.6418 27.1418 33.25 27.625 33.25H31.125C32.5747 33.25 33.75 32.0747 33.75 30.625V27.125Z" fill="#6C6C6C"/>
</svg>
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.0146484 0H3.64665V3.62266H0.0146484V0ZM9.07389 9.0872H10V10H9.07389V9.0872ZM7.29411 9.08558H8.22021V9.95518H7.29411H7.29329H6.368V8.17685H7.26481V7.27547H8.17708V5.4784H9.10319V6.36186H9.98535V7.27465H9.10319V8.18745H8.19092H8.17708H7.29411V9.08558ZM4.54427 7.2608H5.44108V6.348H4.57357V5.43521H5.44108V4.52241H4.55892V5.43521H3.632V4.52241H4.54346V1.81174H5.46956V4.5216H6.36637V5.43439H7.24854V4.5216H8.17464V5.43439H7.29411V6.34719H6.368V8.14425H5.47038V9.95599H4.54427V7.2608ZM9.05843 4.5216H9.98454V5.43439H9.05843V4.5216ZM1.82373 4.5216H2.74984V5.43439H1.82373V4.5216ZM0.0146484 4.5216H0.940755V5.43439H0.0146484V4.5216ZM4.54427 0H5.47038V0.912795H4.54427V0ZM0 6.36186H3.632V9.98452H0V6.36186ZM0.882161 7.24205H2.74984V9.10513H0.882161V7.24205ZM6.35254 0H9.98454V3.62266H6.35254V0ZM7.23551 0.880196H9.10319V2.74328H7.23551V0.880196ZM0.89681 0.880196H2.76449V2.74328H0.89681V0.880196Z" fill="white"/>
</svg>
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M38.3333 1.66644V31.6664H33.3333V29.9998H36.6666V3.33311H3.33329V29.9998H16.6666V31.6664H1.66663V1.66644H38.3333ZM26.6666 4.99978H13.3333V6.66644H26.6666V4.99978ZM23.3333 9.99978V8.33311H16.6666V9.99978H23.3333ZM11.6666 18.3331H4.99996V19.9998H11.6666V18.3331ZM11.6666 21.6664H4.99996V23.3331H11.6666V21.6664ZM4.99996 26.6664H8.33329V24.9998H4.99996V26.6664ZM28.3333 21.6664C28.3333 22.3257 28.1378 22.9702 27.7715 23.5183C27.4053 24.0665 26.8847 24.4937 26.2756 24.746C25.6665 24.9983 24.9963 25.0643 24.3497 24.9357C23.7031 24.8071 23.1091 24.4896 22.6429 24.0235C22.1768 23.5573 21.8593 22.9633 21.7307 22.3167C21.6021 21.6701 21.6681 20.9999 21.9204 20.3908C22.1727 19.7817 22.5999 19.2611 23.1481 18.8949C23.6962 18.5286 24.3407 18.3331 25 18.3331C25.8837 18.334 26.7311 18.6855 27.356 19.3104C27.9809 19.9353 28.3324 20.7827 28.3333 21.6664ZM26.6666 21.6664C26.6666 21.3368 26.5689 21.0146 26.3857 20.7405C26.2026 20.4664 25.9423 20.2528 25.6378 20.1266C25.3332 20.0005 24.9981 19.9675 24.6748 20.0318C24.3515 20.0961 24.0545 20.2548 23.8215 20.4879C23.5884 20.721 23.4296 21.018 23.3653 21.3413C23.301 21.6646 23.334 21.9997 23.4602 22.3042C23.5863 22.6088 23.7999 22.8691 24.074 23.0522C24.3481 23.2354 24.6703 23.3331 25 23.3331C25.4419 23.3327 25.8655 23.1569 26.178 22.8445C26.4905 22.532 26.6662 22.1083 26.6666 21.6664ZM26.67 14.5114C26.7452 14.723 26.8638 14.9164 27.0183 15.0793C27.1727 15.2422 27.3596 15.371 27.5668 15.4574C27.774 15.5437 27.997 15.5857 28.2215 15.5807C28.4459 15.5756 28.6668 15.5237 28.87 15.4281C29.202 15.273 29.5735 15.2229 29.9347 15.2845C30.296 15.3462 30.6298 15.5166 30.8916 15.7731C31.1508 16.0321 31.3236 16.365 31.3862 16.726C31.4489 17.087 31.3984 17.4586 31.2416 17.7898C31.1451 17.9931 31.0923 18.2143 31.0866 18.4393C31.0809 18.6643 31.1224 18.8879 31.2085 19.0958C31.2946 19.3038 31.4233 19.4913 31.5863 19.6465C31.7493 19.8016 31.943 19.9208 32.155 19.9964C32.4994 20.1195 32.7974 20.346 33.008 20.6449C33.2187 20.9439 33.3318 21.3007 33.3318 21.6664C33.3318 22.0322 33.2187 22.389 33.008 22.6879C32.7974 22.9869 32.4994 23.2134 32.155 23.3364C31.9429 23.4117 31.7491 23.5306 31.5859 23.6855C31.4227 23.8404 31.2938 24.0278 31.2076 24.2356C31.1213 24.4435 31.0797 24.6671 31.0852 24.892C31.0908 25.1169 31.1435 25.3382 31.24 25.5414C31.3576 25.7828 31.4182 26.0479 31.417 26.3164C31.4157 26.5849 31.3527 26.8495 31.2329 27.0898C31.113 27.33 30.9394 27.5395 30.7256 27.7019C30.5119 27.8643 30.2636 27.9754 30 28.0264V39.7698L25 35.5398L20 39.7698V28.0264C19.7366 27.9753 19.4885 27.8643 19.2749 27.7019C19.0613 27.5396 18.8879 27.3304 18.768 27.0903C18.6482 26.8503 18.5851 26.5859 18.5837 26.3177C18.5823 26.0494 18.6426 25.7844 18.76 25.5431C18.8567 25.3397 18.9096 25.1183 18.9153 24.8932C18.9211 24.6681 18.8795 24.4443 18.7932 24.2363C18.707 24.0283 18.578 23.8407 18.4146 23.6857C18.2513 23.5307 18.0572 23.4117 17.845 23.3364C17.5005 23.2134 17.2026 22.9869 16.9919 22.6879C16.7812 22.389 16.6681 22.0322 16.6681 21.6664C16.6681 21.3007 16.7812 20.9439 16.9919 20.6449C17.2026 20.346 17.5005 20.1195 17.845 19.9964C18.057 19.921 18.251 19.8019 18.4142 19.6468C18.5774 19.4918 18.7062 19.3042 18.7924 19.0963C18.8787 18.8883 18.9203 18.6646 18.9147 18.4396C18.9091 18.2145 18.8564 17.9932 18.76 17.7898C18.603 17.4587 18.5522 17.0873 18.6146 16.7263C18.677 16.3652 18.8494 16.0323 19.1083 15.7731C19.3701 15.5173 19.7038 15.3473 20.0647 15.286C20.4256 15.2246 20.7966 15.2748 21.1283 15.4298C21.3315 15.5253 21.5526 15.5772 21.7771 15.5821C22.0016 15.587 22.2247 15.5449 22.4319 15.4584C22.6392 15.3719 22.826 15.2429 22.9804 15.0798C23.1348 14.9167 23.2533 14.7231 23.3283 14.5114C23.451 14.1664 23.6775 13.8679 23.9766 13.6567C24.2758 13.4456 24.633 13.3323 24.9991 13.3323C25.3653 13.3323 25.7225 13.4456 26.0216 13.6567C26.3208 13.8679 26.5473 14.1664 26.67 14.5114ZM28.3333 36.1781V27.7781C27.9784 27.7331 27.6189 27.8123 27.3158 28.0022C27.0126 28.192 26.7844 28.4809 26.67 28.8198C26.5469 29.1642 26.3204 29.4622 26.0215 29.6728C25.7225 29.8835 25.3657 29.9966 25 29.9966C24.6342 29.9966 24.2774 29.8835 23.9785 29.6728C23.6795 29.4622 23.453 29.1642 23.33 28.8198C23.2155 28.4809 22.9873 28.192 22.6842 28.0022C22.381 27.8123 22.0215 27.7331 21.6666 27.7781V36.1764L25 33.3564L28.3333 36.1781ZM25.1 28.2631C25.3267 27.6254 25.7453 27.0735 26.2983 26.6832C26.8512 26.2928 27.5115 26.0832 28.1883 26.0831C28.6894 26.0885 29.1837 26.2004 29.6383 26.4114L29.735 26.2598C29.538 25.846 29.4301 25.3955 29.4182 24.9374C29.4063 24.4792 29.4908 24.0237 29.6662 23.6003C29.8415 23.1769 30.1038 22.7951 30.436 22.4794C30.7683 22.1638 31.1631 21.9215 31.595 21.7681V21.5648C31.1634 21.411 30.769 21.1684 30.437 20.8527C30.105 20.537 29.8429 20.1552 29.6677 19.7319C29.4924 19.3087 29.4078 18.8533 29.4194 18.3954C29.431 17.9374 29.5385 17.487 29.735 17.0731L29.59 16.9331C29.1761 17.1295 28.7257 17.2369 28.2678 17.2484C27.8098 17.2599 27.3546 17.1751 26.9314 16.9997C26.5083 16.8242 26.1266 16.562 25.8112 16.2298C25.4957 15.8977 25.2534 15.5031 25.1 15.0714H24.9C24.7465 15.5031 24.5042 15.8977 24.1888 16.2298C23.8733 16.562 23.4917 16.8242 23.0685 16.9997C22.6454 17.1751 22.1901 17.2599 21.7322 17.2484C21.2742 17.2369 20.8238 17.1295 20.41 16.9331L20.265 17.0731C20.4614 17.487 20.5689 17.9374 20.5805 18.3954C20.5921 18.8533 20.5075 19.3087 20.3323 19.7319C20.157 20.1552 19.8949 20.537 19.5629 20.8527C19.231 21.1684 18.8365 21.411 18.405 21.5648V21.7681C18.8368 21.9215 19.2316 22.1638 19.5639 22.4794C19.8962 22.7951 20.1584 23.1769 20.3338 23.6003C20.5091 24.0237 20.5936 24.4792 20.5817 24.9374C20.5699 25.3955 20.462 25.846 20.265 26.2598L20.3616 26.4098C20.8163 26.1993 21.3106 26.088 21.8116 26.0831C22.4885 26.0832 23.1487 26.2928 23.7017 26.6832C24.2546 27.0735 24.6732 27.6254 24.9 28.2631L25 28.3331L25.1 28.2631Z" fill="#2F6BFF"/>
</svg>
<svg width="36" height="40" viewBox="0 0 36 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M34.0417 20C33.655 20 33.284 20.1405 33.0105 20.3905C32.737 20.6406 32.5834 20.9797 32.5834 21.3333V25.3333C32.5834 25.687 32.737 26.0261 33.0105 26.2762C33.284 26.5262 33.655 26.6667 34.0417 26.6667C34.4285 26.6667 34.7994 26.5262 35.0729 26.2762C35.3464 26.0261 35.5001 25.687 35.5001 25.3333V21.3333C35.5001 20.9797 35.3464 20.6406 35.0729 20.3905C34.7994 20.1405 34.4285 20 34.0417 20ZM34.8584 14.8933C34.7773 14.8426 34.689 14.8022 34.5959 14.7733C34.5089 14.7332 34.4153 14.7062 34.3188 14.6933C34.0845 14.6504 33.8423 14.6608 33.6134 14.7236C33.3846 14.7864 33.1761 14.8996 33.0063 15.0533C32.8712 15.1779 32.7642 15.3257 32.6916 15.4881C32.6191 15.6506 32.5823 15.8245 32.5834 16C32.5834 16.3536 32.737 16.6928 33.0105 16.9428C33.284 17.1929 33.655 17.3333 34.0417 17.3333C34.4285 17.3333 34.7994 17.1929 35.0729 16.9428C35.3464 16.6928 35.5001 16.3536 35.5001 16C35.4947 15.647 35.3436 15.3089 35.0771 15.0533L34.8584 14.8933Z" fill="#2F6BFF"/>
<path d="M31.125 4H29.6667C29.6667 2.93913 29.2057 1.92172 28.3853 1.17157C27.5648 0.421427 26.452 0 25.2917 0H10.7083C9.54801 0 8.43521 0.421427 7.61474 1.17157C6.79427 1.92172 6.33333 2.93913 6.33333 4H4.875C3.73461 3.99963 2.63913 4.40638 1.82194 5.13361C1.00474 5.86084 0.53041 6.85106 0.5 7.89333V36.1067C0.53041 37.1489 1.00474 38.1392 1.82194 38.8664C2.63913 39.5936 3.73461 40.0004 4.875 40H31.125C32.2654 40.0004 33.3609 39.5936 34.1781 38.8664C34.9953 38.1392 35.4696 37.1489 35.5 36.1067V29.3333C35.5 28.9797 35.3464 28.6406 35.0729 28.3905C34.7994 28.1405 34.4284 28 34.0417 28C33.6549 28 33.284 28.1405 33.0105 28.3905C32.737 28.6406 32.5833 28.9797 32.5833 29.3333V36.1067C32.5539 36.4415 32.3874 36.7538 32.117 36.9812C31.8467 37.2087 31.4924 37.3344 31.125 37.3333H4.875C4.50762 37.3344 4.15332 37.2087 3.88295 36.9812C3.61258 36.7538 3.44606 36.4415 3.41667 36.1067V7.89333C3.44606 7.55851 3.61258 7.24617 3.88295 7.01875C4.15332 6.79133 4.50762 6.66559 4.875 6.66667H6.33333C6.33333 7.72753 6.79427 8.74495 7.61474 9.49509C8.43521 10.2452 9.54801 10.6667 10.7083 10.6667H25.2917C26.452 10.6667 27.5648 10.2452 28.3853 9.49509C29.2057 8.74495 29.6667 7.72753 29.6667 6.66667H31.125C31.4924 6.66559 31.8467 6.79133 32.117 7.01875C32.3874 7.24617 32.5539 7.55851 32.5833 7.89333V10.6667C32.5833 11.0203 32.737 11.3594 33.0105 11.6095C33.284 11.8595 33.6549 12 34.0417 12C34.4284 12 34.7994 11.8595 35.0729 11.6095C35.3464 11.3594 35.5 11.0203 35.5 10.6667V7.89333C35.4696 6.85106 34.9953 5.86084 34.1781 5.13361C33.3609 4.40638 32.2654 3.99963 31.125 4ZM26.75 6.66667C26.75 7.02029 26.5964 7.35943 26.3229 7.60948C26.0494 7.85952 25.6784 8 25.2917 8H10.7083C10.3216 8 9.95063 7.85952 9.67714 7.60948C9.40365 7.35943 9.25 7.02029 9.25 6.66667V4C9.25 3.64638 9.40365 3.30724 9.67714 3.05719C9.95063 2.80714 10.3216 2.66667 10.7083 2.66667H25.2917C25.6784 2.66667 26.0494 2.80714 26.3229 3.05719C26.5964 3.30724 26.75 3.64638 26.75 4V6.66667Z" fill="#2F6BFF"/>
<path d="M27.1292 16.44L15.0833 28.7333L8.82708 23.0533C8.5481 22.8349 8.18924 22.7207 7.82221 22.7337C7.45519 22.7467 7.10702 22.8858 6.8473 23.1232C6.58758 23.3607 6.43543 23.679 6.42125 24.0146C6.40708 24.3502 6.53192 24.6783 6.77083 24.9333L14.0625 31.6C14.3318 31.8512 14.6987 31.995 15.0833 32C15.2819 31.9959 15.4775 31.9547 15.658 31.8791C15.8386 31.8034 16.0003 31.6948 16.1333 31.56L29.2583 18.2267C29.5175 17.9632 29.6515 17.6164 29.631 17.2626C29.6105 16.9088 29.4371 16.5769 29.149 16.34C28.8608 16.1031 28.4815 15.9805 28.0945 15.9992C27.7075 16.018 27.3446 16.1765 27.0854 16.44H27.1292Z" fill="#2F6BFF"/>
</svg>
<svg width="none" height="none" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.1917 17.1569L22 22M19.7778 10.8889C19.7778 15.7981 15.7981 19.7778 10.8889 19.7778C5.97969 19.7778 2 15.7981 2 10.8889C2 5.97969 5.97969 2 10.8889 2C15.7981 2 19.7778 5.97969 19.7778 10.8889Z" stroke="none" stroke-width="none" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<svg width="38" height="41" viewBox="0 0 38 41" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.2223 20.5001H13.1667M26.7778 20.5001H19.0001" stroke="#2F6BFF" stroke-width="4" stroke-linecap="round"/>
<path d="M26.7778 12.7217H24.8334M19.0001 12.7217H11.2223" stroke="#2F6BFF" stroke-width="4" stroke-linecap="round"/>
<path d="M11.2223 28.2775H20.9445" stroke="#2F6BFF" stroke-width="4" stroke-linecap="round"/>
<path d="M1.5 24.3889V16.6111C1.5 9.27813 1.5 5.61167 3.77805 3.33359C6.05612 1.05554 9.72259 1.05554 17.0556 1.05554H20.9444C28.2773 1.05554 31.944 1.05554 34.2219 3.33359C35.492 4.60369 36.0539 6.30533 36.3026 8.83332M36.5 16.6111V24.3889C36.5 31.7218 36.5 35.3884 34.2219 37.6663C31.944 39.9444 28.2773 39.9444 20.9444 39.9444H17.0556C9.72259 39.9444 6.05612 39.9444 3.77805 37.6663C2.50798 36.3962 1.946 34.6946 1.69734 32.1667" stroke="#2F6BFF" stroke-width="2" stroke-linecap="round"/>
</svg>
<svg width="36" height="37" viewBox="0 0 36 37" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M33.1437 30.0397C33.1437 30.0259 33.2401 26.9461 34.7214 25.4717C34.9833 25.2099 34.9901 24.7828 34.8317 24.4452C34.6663 24.1076 34.3287 23.894 33.9567 23.894H7.17617C3.81397 23.894 1.07184 26.6292 1.07184 29.9983C1.07184 33.3605 3.80708 36.1026 7.17617 36.1026H33.9567C34.3287 36.1026 34.6663 35.8891 34.8317 35.5515C34.997 35.2139 34.9488 34.8211 34.7214 34.5249C33.6742 33.2089 33.1507 31.6243 33.1437 30.0397ZM7.44487 30.9698H31.249C31.3661 32.0652 31.6762 33.1469 32.186 34.1528H7.17617C4.88188 34.1528 3.01475 32.2857 3.01475 29.9914C3.01475 27.6971 4.88188 25.83 7.17617 25.83H32.186C31.6762 26.8428 31.3661 27.9176 31.249 29.0131H7.44487C6.90747 29.0131 6.47341 29.4471 6.47341 29.9845C6.47341 30.5357 6.90747 30.9698 7.44487 30.9698Z" fill="#2F6BFF"/>
<path d="M34.7972 5.64611L18.2687 0.93351C18.0965 0.885282 17.9104 0.885282 17.7382 0.93351L1.20276 5.64611C0.78937 5.77012 0.5 6.14906 0.5 6.58312C0.5 7.01717 0.78937 7.39611 1.20276 7.52012L7.31398 9.26324V20.7347C7.31398 21.0861 7.50689 21.4099 7.81004 21.5821C8.12008 21.7544 8.49213 21.7475 8.79528 21.5615C11.8612 19.6806 14.9547 18.7298 18 18.7298C21.0453 18.7298 24.1319 19.6806 27.2047 21.5615C27.3632 21.6579 27.8317 21.7819 28.19 21.5821C28.5 21.4099 28.686 21.0861 28.686 20.7347V9.26324L31.9035 8.3469V13.7347C31.9035 14.2721 32.3376 14.7061 32.875 14.7061C33.4124 14.7061 33.8465 14.2721 33.8465 13.7347V7.78883L34.7972 7.52012C35.2175 7.403 35.5 7.01717 35.5 6.58312C35.5 6.14906 35.2106 5.77012 34.7972 5.64611ZM9.26378 19.0674V9.82131L17.7313 12.2396C17.9035 12.2878 18.0896 12.2878 18.2618 12.2396L26.7293 9.82131V19.0639C23.831 17.5505 20.9052 16.7869 18 16.7869C15.0925 16.7869 12.1575 17.5516 9.26378 19.0674ZM18 10.2898L5.01968 6.58312L18 2.88331L30.9803 6.58312L18 10.2898Z" fill="#2F6BFF"/>
</svg>
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M27.1244 8.53633L25.2745 6.03968C25.1555 5.88122 25.0006 5.75329 24.8224 5.66646C24.6442 5.57964 24.4478 5.53641 24.2496 5.54035H12.0004C11.8198 5.54033 11.6414 5.57938 11.4774 5.65481C11.3135 5.73023 11.1678 5.84023 11.0505 5.97725L8.90058 8.47392C8.71596 8.70353 8.61856 8.99093 8.6256 9.28534V18.3857C8.6289 20.5598 9.49516 22.644 11.0345 24.1813C12.5739 25.7188 14.6606 26.5839 16.8376 26.5872H19.1624C21.3393 26.5839 23.4262 25.7188 24.9656 24.1813C26.5048 22.644 27.371 20.5598 27.3744 18.3857V9.28534C27.3744 9.01523 27.2867 8.75241 27.1244 8.53633Z" fill="white"/>
<path d="M35.2239 33.4777L30.2242 27.236C30.0792 27.0514 29.885 26.9112 29.664 26.8318C29.4429 26.7523 29.2039 26.7367 28.9743 26.7866L18 29.2583L7.0257 26.7617C6.79613 26.7117 6.55708 26.7273 6.33601 26.8068C6.11494 26.8862 5.92076 27.0264 5.77578 27.2111L0.776111 33.4527C0.631033 33.6355 0.540089 33.855 0.513578 34.0867C0.487067 34.3183 0.526052 34.5529 0.626121 34.7635C0.723814 34.9805 0.881617 35.1653 1.08092 35.2957C1.28023 35.4262 1.51274 35.4971 1.75105 35.5H34.2489C34.4845 35.4993 34.7152 35.4322 34.9141 35.3062C35.1131 35.1804 35.2725 35.0009 35.3739 34.7884C35.4739 34.5778 35.5129 34.3433 35.4864 34.1117C35.4599 33.88 35.369 33.6604 35.2239 33.4777Z" fill="#2F6BFF"/>
<path d="M34.6114 5.54014L18.3625 0.546822C18.1249 0.484393 17.8751 0.484393 17.6375 0.546822L1.38858 5.54014C1.12287 5.62028 0.89144 5.78647 0.73075 6.01249C0.570073 6.23851 0.489291 6.51152 0.50114 6.78848C0.490766 7.06865 0.575135 7.34417 0.740662 7.57063C0.906176 7.79708 1.14322 7.96129 1.41358 8.03681L17.6625 12.5308C17.8825 12.5974 18.1175 12.5974 18.3375 12.5308L34.5864 8.03681C34.8568 7.96129 35.0938 7.79708 35.2594 7.57063C35.4249 7.34417 35.5092 7.06865 35.4989 6.78848C35.5107 6.51152 35.4299 6.23851 35.2692 6.01249C35.1085 5.78647 34.8771 5.62028 34.6114 5.54014Z" fill="#2F6BFF"/>
<path d="M12.0254 5.54022C11.8449 5.54021 11.6664 5.57926 11.5024 5.65468C11.3384 5.73011 11.1928 5.84011 11.0755 5.97714L8.92559 8.4738C8.73197 8.69992 8.62559 8.98769 8.62561 9.28522V18.3855C8.62891 20.5598 9.49517 22.6439 11.0345 24.1813C12.5739 25.7186 14.6606 26.5838 16.8376 26.5871H18V5.54022H12.0254Z" fill="#2F6BFF"/>
<path d="M7.0257 26.7617C6.79613 26.7117 6.55708 26.7273 6.33601 26.8068C6.11494 26.8862 5.92076 27.0264 5.77578 27.2111L0.776111 33.4527C0.631033 33.6355 0.540089 33.855 0.513578 34.0867C0.487067 34.3183 0.526052 34.5529 0.626121 34.7635C0.723814 34.9805 0.881617 35.1653 1.08092 35.2957C1.28023 35.4262 1.51274 35.4971 1.75105 35.5H18V29.2583L7.0257 26.7617Z" fill="#2F6BFF"/>
<path d="M17.6375 0.546884L1.38858 5.54021C1.12287 5.62035 0.89144 5.78653 0.73075 6.01255C0.570073 6.23859 0.489291 6.5116 0.50114 6.78854C0.490766 7.06873 0.575135 7.34424 0.740662 7.57069C0.906176 7.79715 1.14322 7.96137 1.41358 8.03687L17.6625 12.5308C17.7743 12.5491 17.8883 12.5491 18 12.5308V0.546884C17.8799 0.527748 17.7576 0.527748 17.6375 0.546884Z" fill="#2F6BFF"/>
<path d="M1.41358 8.03681L8.62561 9.9842V18.3854C8.62891 20.5597 9.49517 22.6439 11.0345 24.1812C12.5739 25.7185 14.6606 26.5837 16.8376 26.587H19.1624C21.3394 26.5837 23.4261 25.7185 24.9655 24.1812C26.5048 22.6439 27.3711 20.5597 27.3744 18.3854V9.9842L34.5864 8.03681C34.8568 7.9613 35.0938 7.79708 35.2594 7.57063C35.4249 7.34417 35.5092 7.06865 35.4989 6.78848C35.5107 6.51152 35.4299 6.23851 35.2692 6.01249C35.1085 5.78647 34.8771 5.62028 34.6114 5.54015L18.3625 0.546822C18.1249 0.484393 17.8751 0.484393 17.6375 0.546822L1.38858 5.54015C1.12287 5.62028 0.89144 5.78647 0.73075 6.01249C0.570073 6.23851 0.489291 6.51152 0.50114 6.78848C0.490766 7.06865 0.575135 7.34417 0.740662 7.57063C0.906176 7.79708 1.14322 7.9613 1.41358 8.03681ZM24.8745 18.3854C24.8713 19.8975 24.2683 21.3466 23.1979 22.4158C22.1274 23.485 20.6763 24.0871 19.1624 24.0903H16.8376C15.3237 24.0871 13.8726 23.485 12.8021 22.4158C11.7317 21.3466 11.1287 19.8975 11.1254 18.3854V10.6707L17.6625 12.4808C17.8825 12.5475 18.1175 12.5475 18.3375 12.4808L24.8745 10.6707V18.3854ZM18 3.1059L29.7992 6.78848L18 9.9842L6.20077 6.78848L18 3.1059Z" fill="#2F6BFF"/>
<path d="M30.2242 27.236C30.0792 27.0514 29.885 26.9112 29.664 26.8318C29.4429 26.7523 29.2039 26.7367 28.9743 26.7866L18 29.2583L7.0257 26.7617C6.79613 26.7117 6.55708 26.7273 6.33601 26.8068C6.11494 26.8862 5.92076 27.0264 5.77578 27.2111L0.776111 33.4527C0.631033 33.6355 0.540089 33.855 0.513578 34.0867C0.487067 34.3183 0.526052 34.5529 0.626121 34.7635C0.723814 34.9805 0.881617 35.1653 1.08092 35.2957C1.28023 35.4262 1.51274 35.4971 1.75105 35.5H34.2489C34.4845 35.4993 34.7152 35.4322 34.9141 35.3062C35.1131 35.1804 35.2725 35.0009 35.3739 34.7884C35.4739 34.5778 35.5129 34.3433 35.4864 34.1117C35.4599 33.88 35.369 33.6604 35.2239 33.4777L30.2242 27.236ZM4.35088 33.0033L7.23819 29.3956L17.725 31.755C17.9064 31.7923 18.0935 31.7923 18.275 31.755L28.7618 29.4206L31.6491 33.0033H4.35088Z" fill="#2F6BFF"/>
</svg>
// AFTER: Đúng cách - import SVG như component
import ArrowBottomIcon from './icon/arrow_bottom_profile.svg';
import ArrowRightIcon from './icon/arrow_right_schedule.svg';
import BackIcon from './icon/back_header.svg';
import CalendarIcon from './icon/calendar_home.svg';
import CameraIcon from './icon/camera_profile.svg';
import DebtIcon from './icon/debt_home.svg';
import ExamScheduleIcon from './icon/exam_schedule_home.svg';
import ImageIcon from './icon/image_dialog.svg';
import JobIcon from './icon/job_home.svg';
import MedicalIcon from './icon/medical_home.svg';
import OutpatientRegistrationIcon from './icon/outpatient_registration_home.svg';
import PeopleIcon from './icon/people_bottom_tab_bar.svg';
import RFCertificateIcon from './icon/register_for_certificate.svg';
import RollCallIcon from './icon/roll_call_home.svg';
import SearchIcon from './icon/search_header.svg';
import StudyMaterialsIcon from './icon/study_materials_home.svg';
import TrainingPointIcon from './icon/training_point_home.svg';
import TrainingProgramIcon from './icon/training_program_home.svg';
import QrCodeIconButton from './icon/qr_code_button.svg'
import Tick from './icon/tick.png';
import Plus from './icon/icon_plus.svg';
import Date from './icon/date.svg'
import ArrowLeftBlack from './icon/back_header_custom.svg';
import DateDrawer from './icon/day.svg';
import Date3Drawer from './icon/filter3day.svg';
import Menu from './icon/menu.svg'
import FilterWeek from './icon/filter_week.svg';
import FilterMonth from './icon/icon_month.svg';
const images = {
iconWarn: require('./images/iconWarn.png'),
iconSuccess: require('./images/iconSuccess.png'),
iconError: require('./images/iconError.png'),
iconCamera: require('./images/iconCamera.png'),
icHome: require('./images/icHome.png'),
icAccount: require('./images/icAccount.png'),
bg_cannot_connect: require('./images/bg_cannot_connect.png'),
icGallery: require('./images/icGallery.png'),
icPlus: Plus,
igBackgroundSlider:require('./images/background_slider_home.jpg'),
igLogo:require('./images/logo.png'),
icHomeSel:require('./icon/home_tab_navigation.png'),
icHomeUnSel:require('./icon/home_tab_navigation_unsel.png'),
icELearing:require('./icon/e_learning_navigation.png'),
icELearingUnSel:require('./icon/e_learning_navigation_unsel.png'),
icQrCodeUnSel:require('./icon/qr_code_unsel.png'),
icQrCode:require('./icon/qr_code_navigation.png'),
icNotification:require('./icon/notificaton.png'),
icNotificationUnSel:require('./icon/notification_unsel.png'),
icProfile:require('./icon/profile_navigation.png'),
icProfileUn:require('./icon/profile_navigation_unsel.png'),
igProfileDemo:require('./images/image.png'),
icImageDownload:require('./images/icImageDownload.png'),
ic3Date:Date3Drawer,
icDateDrawer:DateDrawer,
icMenu:Menu,
icArrowLeftBlack:ArrowLeftBlack,
icWeek:FilterWeek,
icMonth:FilterMonth,
icArrowBottom: ArrowBottomIcon,
icArrowRight: ArrowRightIcon,
icBack: BackIcon,
icCalendar: CalendarIcon,
icCamera: CameraIcon,
icDebt: DebtIcon,
icExamSchedule: ExamScheduleIcon,
icImage: ImageIcon,
icJob: JobIcon,
icMedical: MedicalIcon,
icOutpatientRegistration: OutpatientRegistrationIcon,
icPeople: PeopleIcon,
icRFCertificate: RFCertificateIcon,
icRollCall: RollCallIcon,
icSearch: SearchIcon,
icStudyMaterials: StudyMaterialsIcon,
icTrainingPoint: TrainingPointIcon,
icTrainingProgram: TrainingProgramIcon,
icQrCodeButton: QrCodeIconButton,
icTick: Tick,
icDate: Date
};
export default images;
import React, {useState} from 'react';
import React from 'react';
import {
Image,
Platform,
SafeAreaView,
StatusBar,
StyleSheet,
Text,
TouchableOpacity,
......@@ -11,30 +7,34 @@ import {
} from 'react-native';
import R from '../../assets/R';
import {
getWidth,
HEIGHTXD,
WIDTHXD,
WIDTHXDICON,
HEIGHT,
getFontSize,
WIDTH,
} from '../../config/Functions';
import Icon from 'react-native-vector-icons/AntDesign';
import {useNavigation} from '@react-navigation/native';
import SnackBar from '../SnackBar';
const Header = props => {
const {title, isBack} = props;
const {title, isBack, isSearch} = props;
const navigate = useNavigation();
const IconBack = R.images.icBack;
const IconSearch = R.images.icSearch;
return (
<View style={styles.headerContainer}>
{isSearch && (
<TouchableOpacity
style={styles.btnSearch}
onPress={() => {}}>
<IconSearch stroke={R.colors.white} strokeWidth={2} width={20} height={20} />
</TouchableOpacity>
)}
<Text numberOfLines={1} style={styles.txtTitle}>
{title}
</Text>
{isBack && (
<TouchableOpacity
style={styles.btnBack}
onPress={() => navigate.goBack()}>
<Icon color={R.colors.black} name={'arrowleft'} size={22} />
<IconBack width={20} height={20} />
</TouchableOpacity>
)}
</View>
......@@ -45,13 +45,13 @@ export default Header;
const styles = StyleSheet.create({
headerContainer: {
height: HEIGHT(45),
height: HEIGHT(50),
width: '100%',
flexDirection: 'row',
alignItems: 'center',
marginBottom: 2,
justifyContent: 'center',
backgroundColor: R.colors.white,
backgroundColor: R.colors.blue500,
shadowColor: '#000',
shadowOffset: {
width: 0,
......@@ -67,12 +67,20 @@ const styles = StyleSheet.create({
fontSize: getFontSize(16),
textAlign: 'center',
fontWeight: 'bold',
color: R.colors.black,
color: R.colors.white,
},
btnBack: {
position: 'absolute',
left: WIDTH(10),
width: WIDTH(35),
left: 5,
width: WIDTH(45),
height: HEIGHT(30),
alignItems: 'center',
justifyContent: 'center',
},
btnSearch: {
position: 'absolute',
right: 5,
width: WIDTH(45),
height: HEIGHT(30),
alignItems: 'center',
justifyContent: 'center',
......
import React from 'react';
import {View, Text, TextInput} from 'react-native';
import {WIDTHXD, getFontXD, WIDTH, HEIGHT} from '../../config/Functions';
import R from '../../assets/R';
import {RFValue} from 'react-native-responsive-fontsize';
const TextField = props => {
const {
title,
onChangeText,
isPassword,
maxLength,
isNumber,
value,
editable,
error,
} = props;
const renderMess = () => {
if (value && value.trim().length > 0) return `${title} không hợp lệ`;
return `Vui lòng nhập ${title ? title.toLowerCase() : messageError} `;
};
return (
<View style={{marginVertical: 5, marginHorizontal: WIDTH(15)}}>
<Text
style={{
fontSize: 16,
color: R.colors.color777,
marginBottom: 5,
}}>
{title ? title : ''}
</Text>
<TextInput
maxLength={maxLength ? maxLength : 256}
placeholderTextColor={R.colors.placeHolder}
editable={editable != null ? editable : true}
secureTextEntry={isPassword}
autoCapitalize="none"
value={value}
keyboardType={isNumber ? 'number-pad' : 'default'}
onChangeText={val => onChangeText(val)}
style={{
height: HEIGHT(35),
color: 'black',
borderRadius: HEIGHT(6),
fontSize: 16,
paddingVertical: 5,
paddingHorizontal: 10,
backgroundColor: '#EFF3F5',
}}
/>
<View
style={{
height: HEIGHT(20),
marginTop: 5,
}}>
{error && !error.ref?.value && (
<Text
ellipsizeMode={'tail'}
numberOfLines={1}
style={{
flex: 1,
color: R.colors.red,
fontSize: RFValue(10),
}}>
{error.message ? error.message : renderMess()}
</Text>
)}
</View>
</View>
);
};
export default React.memo(TextField);
import React, { useRef } from 'react';
import {
View,
Text,
TextInput,
StyleSheet,
Platform,
} from 'react-native';
import R from '../../assets/R';
const CustomTextInput = (props) => {
const {
title,
placeholder,
required,
value,
onChangeText,
backgroundColor, // FUNCTIONALITY: Prop backgroundColor tùy chỉnh
...restProps
} = props;
const inputRef = useRef(null);
return (
<View style={styles.container}>
{/* FUNCTIONALITY: Title với sao đỏ nếu required */}
{title && (
<View style={styles.titleContainer}>
<Text style={styles.title}>
{title}
{required && <Text style={styles.required}> *</Text>}
</Text>
</View>
)}
{/* FUNCTIONALITY: Input container với background tùy chỉnh */}
<View style={[
styles.inputContainer,
backgroundColor && { backgroundColor } // NOTE: Chỉ apply backgroundColor khi có truyền vào
]}>
<TextInput
ref={inputRef}
style={styles.input}
placeholder={placeholder}
placeholderTextColor={R.colors.grey_100}
value={value}
onChangeText={onChangeText}
{...restProps}
/>
</View>
</View>
);
};
const styles = StyleSheet.create({
// FUNCTIONALITY: Container wrapper
container: {
width: '100%',
marginVertical: 5
},
// UI/UX: Container cho title
titleContainer: {
flexDirection: 'row',
marginBottom: 3,
},
// UI/UX: Title text
title: {
fontSize: R.fontsize.fontsSize12,
fontFamily: R.fonts.InterRegular,
fontWeight: '400',
color: R.colors.black
},
// UI/UX: Dấu sao đỏ bắt buộc
required: {
color: R.colors.red,
fontSize: R.fontsize.fontsSize12,
fontFamily: R.fonts.InterRegular,
fontWeight: '500',
},
// UI/UX: Input container - KHÔNG có backgroundColor mặc định
inputContainer: {
// NOTE: Không set backgroundColor ở đây
borderRadius: 10,
borderWidth: 1,
borderColor: R.colors.grey_200,
paddingHorizontal: 15,
},
// UI/UX: Input text styles
input: {
fontSize: R.fontsize.fontsSize10,
fontFamily: R.fonts.InterRegular,
fontWeight: '400',
color: R.colors.black, // FIXME: Đổi từ grey_200 sang black để text rõ hơn
padding: 0,
minHeight: 40,
},
});
export default CustomTextInput;
......@@ -15,7 +15,7 @@ import i18n from '../../helper/i18/i18n';
import {connect} from 'react-redux';
import {hideLoading, showLoading} from '../../actions/loadingAction';
import {uploadFile} from '../../apis/Functions/config';
import {showAlert, TYPE} from '../DropdownAlert';
import {showAlert, TYPE} from '../Dropdown/DropdownAlert';
import {saveUserToRedux} from '../../actions/users';
import {ASYNC_STORE_KEY} from '../../config/constants';
import AsyncStorage from '@react-native-community/async-storage';
......
export default {
EnterPhoneNumberToLogin: 'Enter phone number to login',
Enter: 'Enter',
PhoneNumber: 'Phone number',
VerifyCodeWillSendPhoneNumber:
'The verification code will be sent to the phone number\n you just entered',
Login: 'Login',
ForgotPassword: 'Forgot password?',
TermsOfUse: 'Terms of use',
PrivacyPolicy: 'Privacy policy',
Password: 'Password',
ChangeOtherPhoneNumber: 'Change other phone number',
VerifyCodeWillSend: 'A real 4-digit code will be sent to the phone number ',
ResendVerifyCode: 'Resend verify code',
Continue: 'Next',
FirstLastName: 'First and last name',
CreateCreditCardSuccess: 'Create card credit success',
UpdateCreditCardSuccess: 'Update card credit success',
ReferralCode: 'Referral code (if any)',
And: 'and',
PleaseEnterField: 'Please enter this field',
PleaseSelect: 'Please select ',
PleaseEnter: 'Please enter ',
Go: 'Go',
Upgrade: 'Upgrade',
InvestPackage: 'Invest Package',
AccountBalance: 'Account balance',
Birthday: 'Birthday',
Sex: 'Sex',
Male: 'Male',
Female: 'Female',
IdentifyInfo: 'Identify Information',
IdentifyID: 'Identify ID',
DateOfIdentifyId: 'Date of identify ID',
PlaceOfIdentifyId: 'Place of identify ID',
Hometown: 'Hometown',
Home: 'Home',
Notification: 'Notification',
Account: 'Account',
PersonalInfo: 'Personal Infor',
AboutUs: 'About us',
AccountSupport: 'Support',
Setting: 'Setting',
Logout: 'Logout',
Email: 'Email',
ProvinceCity: 'Province/City',
ContactAddress: 'Contact address',
Update: 'Update',
OnlineSupport: 'Online support',
SupportByOperator: 'Support by operator',
FanpageFacebook: 'Fanpage Facebook',
Terms2: 'Terms',
Version: 'Version',
SupportPhoneNumber: 'Support phone number',
WorkTime: 'Work time',
Address: 'Address',
ChangePassword: 'Change password',
CommonSetting: 'Common setting',
OldPassword: 'Old password',
NewPassword: 'New password',
ConfirmNewPassword: 'Confirm new password',
ReceiveNotification: 'Receive notification',
Language: 'Language',
English: 'English',
Vietnamese: 'Vietnamese',
LogoutConfirm: 'Do you really want to sign out?',
No: 'No',
ResendVerifyCode: 'Resend verify code',
VerifyCode: 'Verification code',
GetVerifyCode: 'Get verification code',
Confirm: 'Confirm',
NullDataSearch: 'No data',
No_Internet: 'No internet',
Select_source_image: 'Select the source of the image',
Photo_library: 'Photo library',
Take_photo: 'Take a photo',
export default {
Search :'Search',
Home:'Home',
Elearning:'Elearning',
QrCode:'QrCode',
Notification:'Notification',
Profile:'Profile',
RollCall:'Roll Call',
Debt:'Debt',
CertificateRegisitor:'Certificate Regisitor',
filterByDay:'Filter by day',
filterBy3Day:'Filter by 3 day',
filterByWeek:'Filter by week',
filterByMonth:'Filter by month',
homeSchedule:'Home schedule',
TrainingPoint:'Training Point',
ExamSchedule:'Exam Schedule'
};
export default {
EnterPhoneNumberToLogin: 'Nhập số điện thoại để đăng nhập',
Enter: 'Nhập',
PhoneNumber: 'Số điện thoại',
VerifyCodeWillSendPhoneNumber:
'Mã xác thực sẽ gửi về số điện thoại\n mà bạn vừa nhập',
Login: 'Đăng nhập',
LoginFalse: 'Đăng nhập thấi bại',
ForgotPassword: 'Quên mật khẩu?',
TermsOfUse: 'Điều khoản sử dụng',
PrivacyPolicy: ' Chính sách bảo mật',
Password: 'Mật khẩu',
ChangeOtherPhoneNumber: 'Đổi số điện thoại khác',
VerifyCodeWillSend: 'Mã các thực gồm 6 chữ số sẽ được gửi đến số điện thoại ',
ResendVerifyCode: 'Gửi lại mã xác nhận',
Continue: 'Tiếp tục',
FirstLastName: 'Họ và tên',
ReferralCode: 'Mã giới thiệu (nếu có)',
And: 'và',
PleaseEnterField: 'Vui lòng nhập trường này',
PleaseSelect: 'Vui lòng chọn ',
PleaseEnter: 'Vui lòng nhập ',
Go: 'Đi vào',
Upgrade: 'Nâng cấp',
Home: 'Trang chủ',
Notification: 'Thông báo',
Account: 'Tài khoản',
PersonalInfo: 'Thông tin cá nhân',
AboutUs: 'Về chúng tôi',
AccountSupport: 'Hỗ trợ tài khoản',
Setting: 'Cài đặt',
Logout: 'Đăng xuất',
No: 'Không',
Birthday: 'Ngày sinh',
Sex: 'Giới tính',
Male: 'Nam',
Female: 'Nữ',
IdentifyInfo: 'Thông tin định danh',
IdentifyID: 'Số CMND',
DateOfIdentifyId: 'Ngày cấp',
PlaceOfIdentifyId: 'Nơi cấp',
Hometown: 'Quê quán',
Update: 'Cập nhật',
Ok: 'Đồng ý',
Cancel: 'Hủy',
ProvinceCity: 'Tỉnh/Thành phố',
ContactAddress: 'Địa chỉ liên hệ',
OnlineSupport: 'Hỗ trợ trực tuyến',
SupportByOperator: 'Hỗ trợ qua tổng đài viên',
FanpageFacebook: 'Fanpage Facebook',
Terms2: 'Điều khoản sử dụng',
Version: 'Phiên bản',
SupportPhoneNumber: 'Số điện thoại viên',
WorkTime: 'Thời gian làm việc',
Address: 'Địa chỉ',
NullDataSearch: 'Không có dữ liệu',
ChangePassword: 'Đổi mật khẩu',
CommonSetting: 'Thiết lập chung',
OldPassword: 'Mật khẩu cũ',
NewPassword: 'Mật khẩu mới',
ConfirmNewPassword: 'Xác nhận mật khẩu mới',
ReceiveNotification: 'Nhận thông báo',
Language: 'Ngôn ngữ',
English: 'Tiếng Anh',
Vietnamese: 'Tiếng Việt',
LogoutConfirm: 'Bạn thật sự muốn đăng xuất không?',
GetVerifyCode: 'Nhận mã xác thực',
VerifyCode: 'Mã xác thực',
Confirm: 'Xác nhận',
No_Internet: 'Không có kết nốt Internet',
Check_Internet_Connect: 'Kiểm tra lại đường truyền',
Retry: 'Thử lại',
Select_source_image: 'Chọn nguồn lấy ảnh',
Photo_library: 'Thư viện ảnh',
Take_photo: 'Chụp ảnh',
Search:'Tìm kiếm',
Home:'Trang chủ',
Elearning:'Học trực tuyến',
QrCode:'Máy quét',
Notification:'Thông báo',
Profile:'Cá nhân',
RollCall:'Điểm danh',
Debt:'Công nợ',
CertificateRegisitor:'Đăng kí chứng chỉ',
filterByDay:'Lọc theo ngày',
filterBy3Day:'Lọc 3 ngày',
filterByWeek:'Lọc theo tuần',
filterByMonth:'Lọc theo tháng',
homeSchedule:'Trang chủ lịch học',
TrainingPoint:'Điểm rèn luyện',
ExamSchedule:'Lịch thi'
};
import React, { useEffect, useState } from "react";
import {
DeviceEventEmitter,
Image,
StyleSheet,
Text,
TouchableOpacity,
View,
} from "react-native";
import { createDrawerNavigator } from "@react-navigation/drawer";
import { connect } from "react-redux";
import ClassSchedule from "../../screens/class_schedule";
import FilterDateView from '../../screens/class_schedule/filter_date';
import * as ScreenName from "../ScreenNames";
import CustomDrawerContent from "./itemDrawer";
import R from "../../assets/R";
import FilterWeekView from "../../screens/class_schedule/filter_week/view";
import Filter3Date from "../../screens/class_schedule/filter_3_date";
const Drawer = createDrawerNavigator();
const ArrowLeft = R.images.icBack;
const IconMenu = R.images.icMenu;
const IconSearch = R.images.icSearch;
const DrawerNavigatorView = (props) => {
const [reload, setReload] = useState(false);
const [currentDate, setCurrentDate] = useState(new Date());
const HeaderBackButton = ({ onPress, canGoBack }) => (
<TouchableOpacity
style={styles.headerBackButton}
onPress={onPress}
activeOpacity={0.7}
>
<ArrowLeft fill={"white"} />
</TouchableOpacity>
);
useEffect(() => {
const setLanguageListener = DeviceEventEmitter.addListener(
"setLanguage",
(value) => {
setReload((prev) => !prev);
}
);
const dateChangeListener = DeviceEventEmitter.addListener(
"onDateChange",
(date) => {
setCurrentDate(new Date(date));
}
);
return () => {
setLanguageListener.remove();
dateChangeListener.remove();
};
}, []);
const MenuButton = ({ onPress }) => (
<TouchableOpacity style={styles.menuButton} onPress={onPress}>
<IconMenu width={24} height={24} stroke={R.colors.white}/>
</TouchableOpacity>
);
const HeaderTitle = ({ navigation, route }) => {
const getHeaderTitle = () => {
if (route.name === ScreenName.FILTERDATE) {
return `Tháng ${currentDate.getMonth() + 1}`;
}
if (route.name === ScreenName.FILTER3DATE) {
return `Tháng ${currentDate.getMonth() + 1}`;
}
if (route.name === ScreenName.FILTERWEEK) {
return `Tháng ${currentDate.getMonth() + 1}`;
}
return '';
};
return (
<TouchableOpacity style={styles.headerTitleButton}>
<Text style={styles.headerTitleText}>
{getHeaderTitle()}
</Text>
</TouchableOpacity>
);
};
return (
<Drawer.Navigator
drawerContent={(drawerProps) => <CustomDrawerContent {...drawerProps} />}
initialRouteName={ScreenName.CLASSSCHEDULE}
screenOptions={({ navigation, route }) => ({
headerLeft: () => (
<View style={styles.headerLeftContainer}>
<HeaderBackButton
onPress={() => {
if (navigation.canGoBack()) {
navigation.pop();
} else {
navigation.toggleDrawer();
}
}}
canGoBack={navigation.canGoBack()}
/>
<MenuButton
onPress={() => {
navigation.toggleDrawer();
}}
/>
</View>
),
headerTitle: () => (
<HeaderTitle navigation={navigation} route={route} />
),
headerRight: () => (
<View style={styles.headerRightContainer}>
<TouchableOpacity style={styles.searchButton}>
<IconSearch stroke={R.colors.white} width={24} height={24} />
</TouchableOpacity>
<View style={styles.avatarButton} />
</View>
),
headerStyle: {
backgroundColor: R.colors.blue500,
},
})}
>
<Drawer.Screen
name={ScreenName.CLASSSCHEDULE}
component={ClassSchedule}
options={{
drawerLabel: () => null,
drawerIcon: () => null,
drawerItemStyle: { height: 0 },
}}
/>
<Drawer.Screen
name={ScreenName.FILTER3DATE}
component={Filter3Date}
options={{
drawerLabel: () => null,
drawerIcon: () => null,
drawerItemStyle: { height: 0 },
}}
/>
<Drawer.Screen
name={ScreenName.FILTERDATE}
component={FilterDateView}
options={{
drawerItemStyle: { height: 0 },
}}
/>
<Drawer.Screen
name={ScreenName.FILTERWEEK}
component={FilterWeekView}
options={{
drawerItemStyle: { height: 0 },
}}
/>
</Drawer.Navigator>
);
};
const mapStateToProps = (state) => ({
user: state.userReducer,
});
const styles = StyleSheet.create({
headerBackButton: {
padding: 10,
marginLeft: 10,
borderRadius: 8,
},
menuButton: {
padding: 10,
marginLeft: 5,
},
headerLeftContainer: {
flexDirection: "row",
alignItems: "center",
},
headerRightContainer: {
flexDirection: "row",
alignItems: "center",
marginRight: 15,
},
searchButton: {
padding: 10,
marginRight: 10,
},
avatarButton: {
width: 30,
height: 30,
borderRadius: 30,
backgroundColor: R.colors.white,
},
headerTitleButton: {
alignItems: 'center',
justifyContent: 'center',
},
headerTitleText: {
fontSize: R.fontsize.fontsSize16,
color: R.colors.white,
fontFamily: R.fonts.InterMedium,
},
});
export default connect(mapStateToProps, {})(DrawerNavigatorView);
\ No newline at end of file
/**
* ENTRY_POINT: Drawer Navigation Module
* FUNCTIONALITY: Export chính cho drawer navigation system
* FEATURE: Tách biệt logic và giao diện, dễ maintain
*/
// COMPONENT: Import component chính
import DrawerNavigator from './drawerView';
// COMPONENT: Export các component con nếu cần sử dụng riêng
export { default as CustomDrawerContent } from './itemDrawer';
// EXPORT: Export mặc định là DrawerNavigator
export default DrawerNavigator;
/**
* USAGE EXAMPLE:
*
* // Sử dụng drawer navigator chính
* import DrawerNavigator from './drawer';
*
* // Hoặc sử dụng riêng CustomDrawerContent
* import { CustomDrawerContent } from './drawer';
*/
\ No newline at end of file
import React, { useState, useMemo, useCallback } from "react";
import {
DeviceEventEmitter,
View,
Text,
Image,
TouchableOpacity,
StyleSheet,
} from "react-native";
import {
DrawerContentScrollView,
useDrawerProgress,
} from "@react-navigation/drawer";
import R from "../../assets/R";
import Checkbox from "../../components/CheckBox";
import * as ScreenName from "../ScreenNames";
const IcDate = R.images.icDateDrawer;
const Ic3Date = R.images.ic3Date;
const IcWeek = R.images.icWeek;
const IcMonth = R.images.icMonth;
const CustomDrawerContent = (props) => {
const progress = useDrawerProgress();
const { navigation, state } = props;
const checkboxConfigs = useMemo(
() => [
{ key: "departmentCalendar", label: "Lịch phòng ban" },
{ key: "personalCalendar", label: "Lịch cá nhân" },
{ key: "teachingCalendar", label: "Lịch giảng dạy" },
{ key: "examCalendar", label: "Lịch coi thi" },
{ key: "examRoomCalendar", label: "Lịch sử dụng phòng thi" },
],
[]
);
const filterConfigs = useMemo(
() => [
{
label: "Theo ngày",
screenName: ScreenName.FILTERDATE,
icon: <IcDate stroke={'black'}/>
},
{
label: "3 ngày",
screenName: ScreenName.FILTER3DATE,
icon: <Ic3Date />
},
{
label: "Tuần",
screenName: ScreenName.FILTERWEEK,
icon: <IcWeek />
},
{
label: "Tháng",
screenName: ScreenName.CLASSSCHEDULE,
icon: <IcMonth />
},
],
[]
);
const [checkboxStates, setCheckboxStates] = useState({
departmentCalendar: false,
personalCalendar: false,
teachingCalendar: false,
examCalendar: false,
examRoomCalendar: false,
});
const currentRouteName = state.routes[state.index]?.name;
const handleCheckboxChange = useCallback((key, newValue) => {
setCheckboxStates((prev) => ({
...prev,
[key]: newValue,
}));
DeviceEventEmitter.emit("onCheckboxChange", { key, value: newValue });
}, []);
const handleScreenNavigation = useCallback((screenName) => {
navigation.navigate(screenName);
navigation.closeDrawer();
}, [navigation]);
const renderCheckbox = useCallback(
(config) => (
<Checkbox
key={config.key}
value={checkboxStates[config.key]}
onValueChange={(newValue) => handleCheckboxChange(config.key, newValue)}
label={config.label}
labelSpacing={30}
size={25}
labelSize={R.fontsize.fontsSize16}
checkedColor={R.colors.black}
marginBottom={20}
labelFontFamily={R.fonts.InterRegular}
labelWeight={400}
/>
),
[checkboxStates, handleCheckboxChange]
);
const renderFilterItem = useCallback(
(item) => {
const isSelected = currentRouteName === item.screenName;
return (
<TouchableOpacity
key={item.screenName}
style={[
styles.filterItem,
isSelected && styles.filterItemSelected,
]}
onPress={() => handleScreenNavigation(item.screenName)}
activeOpacity={0.7}
>
{item.icon}
<Text style={[
styles.filterLabel,
isSelected && styles.filterLabelSelected
]}>
{item.label}
</Text>
</TouchableOpacity>
);
},
[currentRouteName, handleScreenNavigation]
);
return (
<DrawerContentScrollView
{...props}
contentContainerStyle={styles.scrollContainer}
>
<View style={styles.logoContainer}>
<Image
source={R.images.igLogo}
style={styles.logo}
resizeMode="contain"
/>
</View>
<View style={styles.filterSection}>
{filterConfigs.map(renderFilterItem)}
</View>
<View style={styles.divider} />
<View style={styles.checkboxSection}>
<Text style={styles.sectionTitle}>Loi lch</Text>
{checkboxConfigs.map(renderCheckbox)}
</View>
</DrawerContentScrollView>
);
};
const styles = StyleSheet.create({
scrollContainer: {
flexGrow: 1,
paddingBottom: 20,
},
logoContainer: {
alignItems: "center",
marginVertical: 20,
},
logo: {
width: 49,
height: 24,
},
filterSection: {
paddingHorizontal: 0,
},
filterItem: {
flexDirection: "row",
alignItems: "center",
paddingVertical: 10,
paddingHorizontal: 15,
marginVertical: 4,
},
filterItemSelected: {
backgroundColor: R.colors.blue100,
borderRadius: 50,
marginHorizontal: 15,
},
filterLabel: {
marginLeft: 30,
fontSize: R.fontsize.fontsSize16,
color: R.colors.black,
flex: 1,
fontFamily: R.fonts.InterMedium,
fontWeight: '400',
},
filterLabelSelected: {
color: R.colors.blue,
fontFamily: R.fonts.InterSemiBold,
},
divider: {
height: 1,
backgroundColor: R.colors.black,
marginHorizontal: 15,
marginTop: 21,
},
checkboxSection: {
paddingHorizontal: 15,
marginTop: 24,
},
sectionTitle: {
fontWeight: "400",
fontFamily: R.fonts.InterMedium,
marginBottom: 10,
fontSize: R.fontsize.fontsSize16,
color: R.colors.black,
},
});
export default CustomDrawerContent;
\ No newline at end of file
......@@ -158,7 +158,7 @@ const styles = StyleSheet.create({
width: 60,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#D7E6FF',
backgroundColor: R.colors.white,
borderRadius: 10,
},
txt: {
......
export const LOGINSCREEN = 'LOGINSCREEN';
export const HOMESCREEN = 'HOMESCREEN';
export const TABNAVIGATOR = 'TABNAVIGATOR';
export const ENTER_PASSWORD = 'ENTER_PASSWORD';
export const CONFIRM_OTP = 'CONFIRM_OTP';
export const CHANGE_PHONE_NUMBER_OTP = 'CHANGE_PHONE_NUMBER_OTP';
export const ELEARNINGSCREEN = 'ELEARNINGSCREEN';
export const EXAMSCHEDULE = 'EXAMSCHEDULE';
export const QRCODESCREEN = 'QRCODESCREE';
export const NOTIFICATIONSCREEN = 'NOTIFICATIONSCREEN';
export const PROFILESCREEN = 'PROFILESCREEN';
export const NEWSDETAILS = 'NEWSDETAILS';
export const ROLLCALL = 'ROLLCALL';
export const TRAININGPROGRAM = 'TRAININGPROGRAM';
export const DEBT = 'DEBT';
export const CERTIFICATEREGISTRATION = 'CERTIFICATEREGISTRATION';
export const LISTCERTIFICATE = 'LISTCERTIFICATE';
export const DETAILCERTIFICATE = 'DETAILCERTIFICATE';
export const DETAILROLLCALL = 'DETAILROLLCALL';
export const TRAININGPOINT = 'TRAININGPOINT';
export const PROFILE = 'PROFILE';
export const MEDICAL = 'MEDICAL';
export const OUTPATIENTINFOMATION = 'OUTPATIENTINFOMATION';
export const DRAWERNAVIGATION = 'DRAWERNAVIGATION';
export const CLASSSCHEDULE = 'CLASSSCHEDULE';
export const FILTERDATE = 'FILTERDATE';
export const FILTERWEEK = 'FILTERWEEK';
export const FILTER3DATE = 'FILTER3DATE';
export const DETAILCLASSSCHEDULE = 'DETAILCLASSSCHEDULE';
\ No newline at end of file
......@@ -2,9 +2,26 @@ import React, {Fragment, useRef, useEffect, useState} from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createStackNavigator} from '@react-navigation/stack';
import TabNavigator from './TabNavigation';
import Login from '../screens/login';
import Home from '../screens/home';
import Elearning from '../screens/elearning';
import QrCode from '../screens/qrcode'
import Notification from '../screens/notification'
import Profile from '../screens/profile'
import NewDetails from '../screens/news_details';
import RollCall from '../screens/roll_call';
import TrainingProgram from '../screens/training_program';
import CertificateRegistration from '../screens/certificate_registration';
import ListCertificate from '../screens/certificate_registration/list';
import DetailCertificate from '../screens/certificate_registration/detail';
import DetailRollCall from '../screens/roll_call/detail';
import TrainingPoint from '../screens/training_point'
import Medical from '../screens/medical';
import DrawerNav from './Drawer/index'
import OutpatientInfomation from '../screens/outpatient_information';
import * as ScreenName from './ScreenNames';
import Debt from '../screens/debt';
import DetailClassSchedule from '../screens/class_schedule/detail';
import ExamSchedule from '../screens/exam_schedule';
const Stack = createStackNavigator();
function MyStack(props) {
......@@ -14,9 +31,28 @@ function MyStack(props) {
headerStatusBarHeight: 0,
}}
headerMode={'none'}
initialRouteName={ScreenName.LOGINSCREEN}>
<Stack.Screen name={ScreenName.LOGINSCREEN} component={Login} />
initialRouteName={ScreenName.TABNAVIGATOR}>
<Stack.Screen name = {ScreenName.HOMESCREEN} component = {Home}/>
<Stack.Screen name={ScreenName.TABNAVIGATOR} component={TabNavigator} />
<Stack.Screen name={ScreenName.DRAWERNAVIGATION} component={DrawerNav} />
<Stack.Screen name={ScreenName.ELEARNINGSCREEN} component={Elearning}/>
<Stack.Screen name={ScreenName.QRCODESCREEN} component={QrCode}/>
<Stack.Screen name={ScreenName.NOTIFICATIONSCREEN} component={Notification}/>
<Stack.Screen name={ScreenName.PROFILESCREEN} component={Profile}/>
<Stack.Screen name={ScreenName.NEWSDETAILS} component={NewDetails}/>
<Stack.Screen name={ScreenName.ROLLCALL} component={RollCall}/>
<Stack.Screen name={ScreenName.TRAININGPROGRAM} component={TrainingProgram}/>
<Stack.Screen name={ScreenName.DEBT} component={Debt}/>
<Stack.Screen name={ScreenName.CERTIFICATEREGISTRATION} component={CertificateRegistration}/>
<Stack.Screen name={ScreenName.LISTCERTIFICATE} component={ListCertificate}/>
<Stack.Screen name={ScreenName.DETAILCERTIFICATE} component={DetailCertificate}/>
<Stack.Screen name={ScreenName.DETAILROLLCALL} component={DetailRollCall}/>
<Stack.Screen name={ScreenName.TRAININGPOINT} component={TrainingPoint}/>
<Stack.Screen name={ScreenName.PROFILE} component={Profile}/>
<Stack.Screen name={ScreenName.MEDICAL} component={Medical}/>
<Stack.Screen name={ScreenName.OUTPATIENTINFOMATION} component={OutpatientInfomation}/>
<Stack.Screen name={ScreenName.DETAILCLASSSCHEDULE} component={DetailClassSchedule}/>
<Stack.Screen name={ScreenName.EXAMSCHEDULE} component={ExamSchedule}/>
</Stack.Navigator>
);
}
......
import React, {useEffect, useState} from 'react';
import {DeviceEventEmitter, Image, View} from 'react-native';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import React, { useEffect, useState } from 'react';
import { DeviceEventEmitter, Image, View } from 'react-native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import i18n from '../helper/i18/i18n';
import {connect} from 'react-redux';
import { connect } from 'react-redux';
import R from '../assets/R';
import Account from '../screens/account';
import Home from '../screens/home';
import ELearning from '../screens/elearning';
import QrCode from '../screens/qrcode';
import Notification from '../screens/notification';
import Profile from '../screens/profile';
const Tab = createBottomTabNavigator();
const TabNavigator = props => {
const [reload, setReload] = useState(false);
useEffect(() => {
let setLanguage = DeviceEventEmitter.addListener('setLanguage', value => {
setReload(!reload);
......@@ -24,50 +26,85 @@ const TabNavigator = props => {
return (
<Tab.Navigator
initialRouteName="Screen5"
screenOptions={{headerShown: false}}
tabBarOptions={{
showIcon: true,
showLabel: true,
activeTintColor: R.colors.main,
style: {
borderTopLeftRadius: 24,
borderTopRightRadius: 24,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
screenOptions={{
headerShown: false,
tabBarStyle: {
height: 61, // 👈 Tăng chiều cao ở đây
paddingVertical: 5, // 👈 Tăng padding nếu icon/text bị sát mép dưới
},
shadowOpacity: 0.29,
shadowRadius: 2,
elevation: 7,
justifyContent: 'center',
tabBarActiveTintColor: R.colors.blue500, // active icon/text
tabBarShowLabel: true,
tabBarLabelStyle: {
fontSize: R.fontsize.fontsSize10,
fontWeight: "400",
fontFamily: R.fonts.InterRegular,
},
}}>
tabBarShowIcon: true,
}}
>
<Tab.Screen
name="HomeScreen1"
component={Home}
options={{
tabBarLabel: i18n.t('Home'),
tabBarIcon: ({color, size}) => (
tabBarIcon: ({ focused }) => (
<Image
source={R.images.icHome}
style={{width: size, height: size, tintColor: color}}
source={focused ? R.images.icHomeSel : R.images.icHomeUnSel}
style={{ width: '50%', height: '50%', resizeMode: 'contain' }}
/>
),
}}
/>
<Tab.Screen
name="AccountScreen"
component={Account}
name="Elearning"
component={ELearning}
options={{
tabBarLabel: i18n.t('Elearning'),
tabBarIcon: ({ focused }) => (
<Image
source={focused ? R.images.icELearing : R.images.icELearingUnSel}
style={{ width: '50%', height: '50%', resizeMode: 'contain' }}
/>
),
}}
/>
<Tab.Screen
name="QRScreen"
component={QrCode}
options={{
tabBarLabel: i18n.t('QrCode'),
tabBarIcon: ({ focused }) => (
<Image
source={focused ? R.images.icQrCode : R.images.icQrCodeUnSel}
style={{ width: '70%', height: '70%', resizeMode: 'contain' }}
/>
),
}}
/>
<Tab.Screen
name="Notification"
component={Notification}
options={{
tabBarLabel: i18n.t('Notification'),
tabBarIcon: ({ focused }) => (
<Image
source={focused ? R.images.icNotification : R.images.icNotificationUnSel}
style={{ width: '50%', height: '50%', resizeMode: 'contain' }}
/>
),
}}
/>
<Tab.Screen
name="Profile"
component={Profile}
options={{
tabBarLabel: i18n.t('Account'),
tabBarIcon: ({color, size}) => (
tabBarLabel: i18n.t('Profile'),
tabBarIcon: ({ focused }) => (
<Image
source={R.images.icAccount}
style={{width: size, height: size - 3, tintColor: color}}
resizeMode={'contain'}
source={focused ? R.images.icProfile : R.images.icProfileUn}
style={{ width: '50%', height: '50%', resizeMode: 'contain' }}
/>
),
}}
......
import React, {useEffect, useState} from 'react';
import AccountView from './view';
import {useNavigation} from '@react-navigation/native';
import {connect} from 'react-redux';
import {saveUserToRedux, saveWalletInfo} from '../../actions/users';
import {showLoading, hideLoading} from '../../actions/loadingAction';
import {showAlert, TYPE} from '../../components/DropdownAlert';
const Account = props => {
return <AccountView />;
};
const mapStateToProps = state => {
return {
userInfo: state.userReducer.userInfo,
};
};
export default connect(mapStateToProps, {
saveUserToRedux,
saveWalletInfo,
showLoading,
hideLoading,
})(Account);
import React, {Component} from 'react';
import {View, Text, SafeAreaView, StyleSheet} from 'react-native';
import Header from '../../components/Header/Header';
import i18n from '../../helper/i18/i18n';
import R from '../../assets/R';
import PickerItem from '../../components/Picker/PickerItem';
import DatePicker from '../../components/Picker/PickerDate';
import PickerAvatar from '../../components/Picker/PickerAvatar';
import {WIDTH} from '../../config/Functions';
import AppText from '../../components/AppText';
const AccountView = props => {
return (
<SafeAreaView style={styles.container}>
<Header title={i18n.t('Account')} />
<View style={styles.body}>
<Text>{i18n.t('Account')}</Text>
</View>
</SafeAreaView>
);
};
export default AccountView;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: R.colors.white,
},
body: {
flex: 1,
paddingHorizontal: WIDTH(10),
},
});
import { StyleSheet, Text, View, TouchableOpacity, Image } from 'react-native';
import React from 'react';
import R from '../../assets/R';
const CardButtonImage = ({
onPress,
text = "Tải ảnh ở đây",
width,
height = 150,
disabled = false
}) => {
return (
<TouchableOpacity
style={[
styles.container_image,
{ width, height },
disabled && styles.disabled
]}
onPress={onPress}
disabled={disabled}
activeOpacity={0.7}
>
<View style={styles.image_placeholder}>
</View>
<View>
<Image
source={R.images.icImageDownload}
style={{width:20,height:20, marginRight:5,marginTop:5}}
/>
</View>
<Text style={styles.placeholder_text}>
{text}
</Text>
</TouchableOpacity>
);
};
export default CardButtonImage;
const styles = StyleSheet.create({
container_image: {
justifyContent: 'center',
alignItems: 'center',
marginHorizontal:15,
marginTop:3,
marginBottom:15,
borderWidth: 1,
borderColor: R.colors.blue500,
borderStyle: 'dashed',
borderRadius: 15,
backgroundColor: R.colors.white,
padding: 16,
flexDirection:'row',
flex:1,
},
image_placeholder: {
position: 'absolute',
width: '100%',
height: '100%',
borderRadius: 10,
},
placeholder_text: {
fontSize: R.fontsize.fontsSize14,
fontWeight: '500',
color:R.colors.black,
textAlign: 'center',
letterSpacing: 0.3,
},
disabled: {
opacity: 0.5,
backgroundColor: R.colors.gray400,
}
});
\ No newline at end of file
import React from 'react';
import {Text, View, StyleSheet} from 'react-native';
import DetailCertificateView from './view';
const DetailCertificate = (props) => {
return (
<DetailCertificateView />
);
};
export default DetailCertificate;
import React from "react";
import {
Text,
View,
TouchableOpacity,
StyleSheet,
Image,
SafeAreaView,
ScrollView,
} from "react-native";
import R from "../../../assets/R";
import Header from "../../../components/Header/Header";
const DetailCertificateView = (props) => {
return (
<SafeAreaView style={{flex:1, backgroundColor: R.colors.white}}>
<Header isBack={true} title={"Chứng chỉ toeic"} />
<ScrollView showsVerticalScrollIndicator={false} style={styles.container}>
<View style={styles.container_card}>
<View style={styles.status}>
<Text style={[styles.text_title, { color: R.colors.white }]}>
Chng ch đang được đánh giá
</Text>
</View>
<View style={styles.card_item}>
<View style={styles.header_card_item}>
<Text style={styles.text_title}>Chng ch toeic</Text>
</View>
<View style={styles.image_container}>
<Image
source={R.images.igProfileDemo}
style={styles.image}
/>
</View>
<View >
<Text style={styles.sub_text}>Loi chng ch: TOEIC</Text>
<Text style={styles.sub_text}>Ngày sinh: 23/10/2004</Text>
<Text style={styles.sub_text}>
CCCD/CMND đăng ký: 00228956325
</Text>
<Text style={styles.sub_text}>Ngày thi: 23/10/2024</Text>
<Text style={styles.sub_text}>Tng đim: 875</Text>
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
}}
>
<Text style={styles.sub_text}>Đim nói: 0</Text>
<Text style={styles.sub_text}>Đim nghe: 445</Text>
</View>
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
}}
>
<Text style={styles.sub_text}>Đim đọc: 430</Text>
<Text style={styles.sub_text}>Đim viết: 0</Text>
</View>
<Text style={styles.sub_text}>S TRF: 085692265852</Text>
<Text style={styles.sub_text}>Có hiu lc đến: 23/10/2026</Text>
<Text style={[styles.sub_text, { color: R.colors.main }]}>
Không dùng để đăng ký hc bng
</Text>
</View>
</View>
</View>
</ScrollView>
</SafeAreaView>
);
};
export default DetailCertificateView;
const styles = StyleSheet.create({
container: {
backgroundColor:R.colors.white,
paddingBottom: 10,
},
image: {
maxWidth: '100%',
maxHeight: 200,
resizeMode: "contain",
},
image_container: {
maxWidth: 340,
maxHeight: 200,
alignSelf: "center",
},
status: {
backgroundColor: R.colors.yellow,
borderTopLeftRadius: 15,
borderTopRightRadius: 15,
paddingLeft: 13,
paddingVertical: 5
},
container_card: {
marginVertical: 15,
borderRadius: 15,
marginHorizontal: 15,
backgroundColor: R.colors.white,
shadowColor: R.colors.black,
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 1,
shadowRadius: 2,
elevation: 2,
},
card_item: {
backgroundColor: R.colors.white,
borderBottomLeftRadius: 15,
borderBottomRightRadius: 15,
paddingHorizontal: 15,
paddingVertical: 10,
},
header_card_item: {
justifyContent: "space-between",
flexDirection: "row",
},
text_title: {
fontFamily: R.fonts.InterRegular,
fontSize: R.fontsize.fontsSize14,
fontWeight: "400",
color: R.colors.black,
},
sub_text: {
fontFamily: R.fonts.InterRegular,
fontSize: R.fontsize.fontsSize12,
fontWeight: "300",
lineHeight: 24,
color: R.colors.black,
},
});
import React, { useState ,useMemo} from 'react';
import {Text, View, StyleSheet} from 'react-native';
import CertificateRegistrationView from './view';
const CertificateRegistration = (props) => {
const [titleHeader,setTitleHeader]= useState('CertificateRegisitor')
const [isSelected, setSelection] = useState(false);
const [selectedValue, setSelectedValue] = useState(null);
const [dataListCertificate, setdataListCertificate]= useState([
{
id: 1,
user_info: {
full_name: 'Nguyễn Văn A',
date: '27/11/2004',
identity_card: '0129210102',
},
certificates: [
{
id_certificate: 'cer_1',
type_certificate: 'TOEIC',
status: 'Chờ duyệt',
registered_date: '2025-07-01',
listening_point: '9',
speaking_point:'9',
reading_point:'9',
writing_score:'9',
total_score:'9',
date_exam:'27/02/2021',
date_effective:'28/09/2023',
code_certificate :'192381832183',
image_certificate:'https://sf-static.upanhlaylink.com/img/image_202507281a9a3a8e0a76ab471f9415ee21d9c57e.jpg'
},
],
apply_for_ascholarship: false
},
{
id: 2,
user_info: {
full_name: 'Nguyễn Văn A',
date: '27/11/2004',
identity_card: '0129210102',
},
certificates: [
{
id_certificate: 'cer_1',
type_certificate: 'TOEIC',
status: 'Chờ duyệt',
registered_date: '2025-07-01',
listening_point: '9',
speaking_point:'9',
reading_point:'9',
writing_score:'9',
total_score:'9',
date_exam:'27/02/2021',
date_effective:'28/09/2023',
code_certificate :'192381832183',
image_certificate:'https://sf-static.upanhlaylink.com/img/image_202507281a9a3a8e0a76ab471f9415ee21d9c57e.jpg'
},
],
apply_for_ascholarship: false
},
])
const dropdownData = useMemo(() => {
return dataListCertificate.flatMap(user =>
user.certificates.map(certificate => ({
label: `${user.user_info.full_name} - ${certificate.status}`,
value: user.id,
originalCertificate: certificate,
originalUser: user.user_info
}))
);
}, [dataListCertificate]);
const handleSelect = (item) => {
console.log("Đã chọn:", item);
setSelectedValue(item.value);
};
return (
<CertificateRegistrationView
titleHeader={titleHeader}
dataList={dropdownData}
value={selectedValue}
onSelect={handleSelect}
isSelected={isSelected}
setSelection={setSelection}
/>
);
};
export default CertificateRegistration;
import React from 'react';
import {Text, View, StyleSheet} from 'react-native';
import ListCertificateView from './view';
const ListCertificate = (props) => {
return (
<ListCertificateView />
);
};
export default ListCertificate;
import { Image, StyleSheet, Text, View } from 'react-native'
import React from 'react'
import R from '../../../assets/R'
import Button from '../../../components/Button'
import { useNavigation } from "@react-navigation/native";
import { DETAILCERTIFICATE } from "../../../routers/ScreenNames";
const ItemNav = () => {
const navigation = useNavigation();
return (
<View style={styles.container_card}>
<View style={styles.header_card_item}>
<Text style={styles.text_title_left}>Chng ch toeic</Text>
<Text
onPress={() => navigation.navigate(DETAILCERTIFICATE)}
style={styles.text_title_right}>Chi tiết</Text>
</View>
<View style={styles.image_container}>
<Image
source={R.images.igProfileDemo}
style={styles.image}
/>
</View>
<View style={styles.footer_card_item}>
<View>
<Text style={styles.sub_text}>Trng thái: Đang đánh giá</Text>
<Text style={styles.sub_text}>Ngày đăng ký: 23/10/2024</Text>
<Text style={[styles.sub_text, { color: R.colors.blue500 }]}>Không dùng để đăng ký hc bng</Text>
</View>
<View style={styles.button_container}>
<Button
title={"Huỷ"}
fontFamily={R.fonts.InterRegular}
fontWeight={300}
fontSize={14}
width={61}
height={27}
backgroundColor={R.colors.red}
borderRadius={10}
textColor={R.colors.white}
/>
</View>
</View>
</View>
)
}
export default ItemNav
const styles = StyleSheet.create({
container_card: {
borderRadius: 15,
backgroundColor: R.colors.white,
shadowColor: R.colors.black,
marginVertical: 5,
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 1,
shadowRadius: 2,
elevation: 2,
paddingHorizontal: 15,
paddingVertical: 10,
},
button_container: {
alignSelf: "flex-end",
},
header_card_item: {
justifyContent: "space-between",
flexDirection: "row",
},
footer_card_item: {
justifyContent: "space-between",
flexDirection: "row",
},
image: {
maxWidth: '100%',
maxHeight: 200,
resizeMode: "contain",
},
image_container: {
maxWidth: 340,
maxHeight: 200,
alignSelf: "center",
},
text_title_left: {
fontFamily: R.fonts.InterRegular,
fontSize: R.fontsize.fontsSize14,
fontWeight: '400',
color: R.colors.black
},
text_title_right: {
fontFamily: R.fonts.InterRegular,
fontSize: R.fontsize.fontsSize14,
fontWeight: '400',
textDecorationLine: 'underline',
color: R.colors.main
},
sub_text: {
fontFamily: R.fonts.InterRegular,
fontSize: R.fontsize.fontsSize12,
fontWeight: "300",
color: R.colors.black
}
})
\ No newline at end of file
import React from "react";
import { useNavigation } from "@react-navigation/native";
import {
Text,
View,
StyleSheet,
ScrollView,
SafeAreaView,
} from "react-native";
import Header from "../../../components/Header/Header";
import Button from "../../../components/Button";
import R from "../../../assets/R";
import ItemNav from "./item";
import { CERTIFICATEREGISTRATION } from "../../../routers/ScreenNames";
const ListCetificateView = (props) => {
const { } = props;
const navigate = useNavigation();
return (
<SafeAreaView style={{flex:1, backgroundColor: R.colors.white}}>
<Header isBack={true} isSearch={true} title={"Danh sách chứng chỉ"}
/>
<ScrollView style={styles.container}>
<View style={styles.container_header}>
<Text style={styles.text}>Các chng ch đã đăng kí</Text>
<Button
onPress={() => navigate.navigate(CERTIFICATEREGISTRATION)}
height={27}
borderRadius={10}
textColor={R.colors.white}
fontFamily={R.fonts.InterRegular}
fontWeight={300}
fontSize={R.fontsize.fontsSize12}
iconSpacingLeft={2}
paddingHorizontal={10}
icon={R.images.icPlus}
backgroundColor={R.colors.blue500}
title={"Thêm mới"}
/>
</View>
<View style={styles.container_item}>
<ItemNav />
</View>
</ScrollView>
</SafeAreaView>
);
};
export default ListCetificateView;
const styles = StyleSheet.create({
container: {
flex: 1,
paddingBottom: 10,
backgroundColor: R.colors.white,
},
container_header: {
alignItems: "center",
justifyContent: "space-between",
flexDirection: "row",
marginVertical: 10,
marginHorizontal: 15,
},
text: {
fontFamily: R.fonts.InterSemiBold,
color: R.colors.main,
},
container_item: {
marginHorizontal: 15,
},
});
import React from "react";
import {
Text,
View,
StyleSheet,
ScrollView,
} from "react-native";
import CheckBox from "../../components/CheckBox";
import Header from "../../components/Header/Header";
import I18n from "../../helper/i18/i18n";
import R from "../../assets/R";
import Button from "../../components/Button";
import CardButtonImage from "./card_button";
import DropdownSelect from "../../components/Dropdown/DropdownSel";
import CustomTextInput from "../../components/Input/TextFieldCus";
const CertificateRegistrationView = (props) => {
const { titleHeader, dataList, isSelected, setSelection } = props;
return (
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.scrollContent}>
<View style={styles.container}>
<Header isBack title={I18n.t(titleHeader)} />
<DropdownSelect
title={"Loại chứng chỉ *"}
titleFontFamily={R.fonts.InterRegular}
titleFontSize={R.fontsize.fontsSize12}
titleFontWeight={"400"}
titleColor={R.colors.black}
data={dataList}
placeholder="HS"
placeholderFontFamily={R.fonts.InterRegular}
placeholderFontSize={R.fontsize.fontsSize12}
placeholderFontWeight={"400"}
placeholderColor={R.colors.grey}
borderRadius={10}
height={40}
marginHorizontal={15}
marginVertical={5}
iconColor={R.colors.black}
iconSize={10}
/>
<View style={{ marginHorizontal: 15, }}>
<CustomTextInput
title={"Ngày sinh "}
backgroundColor={R.colors.gray400}
/>
</View>
<View style={{ marginHorizontal: 15 }}>
<CustomTextInput
title={"CMND/CCCD (thí sinh dùng để đăng ký thi)"}
backgroundColor={R.colors.gray400}
/>
</View>
<View style={styles.container_row}>
<View style={{ flex: 1, marginLeft: 15 }}>
<CustomTextInput
title={"Điểm nghe "}
/>
</View>
<View style={{ width: '3%' }}></View>
<View style={{ flex: 1, marginRight: 15 }}>
<CustomTextInput
title={"Điểm nói "}
/>
</View>
</View>
<View style={styles.container_row}>
<View style={{ flex: 1, marginLeft: 15 }}>
<CustomTextInput
title={"Điểm đọc"}
/>
</View>
<View style={{ width: '3%' }}></View>
<View style={{ flex: 1, marginRight: 15 }}>
<CustomTextInput
title={"Điểm viết "}
/>
</View>
</View>
<View
style={styles.container_row}
>
<View style={{ flex: 0.85, marginBottom: 10, marginHorizontal: 15 }}>
<CustomTextInput
title={"Tổng điểm "}
/>
</View>
<CheckBox
label={"Đăng kí học bổng"}
titleFontFamily={R.fonts.InterRegular}
titleFontSize={R.fontsize.fontsSize12}
titleFontWeight={"300"}
borderRadius={30}
size={15}
labelStyle={{
fontSize: R.fontsize.fontsSize12,
fontWeight: "300",
color: R.colors.black,
fontFamily: R.fonts.InterRegular,
}}
style={{ marginTop: 15, flex: 1 }}
/>
</View>
<View style={styles.container_row_body}>
<CustomTextInput
title={"Ngày thi "}
/>
</View>
<View style={styles.container_row_body}>
<CustomTextInput
title={"Có hiệu lực đến"}
/>
</View>
<View style={styles.container_row_body}>
<CustomTextInput
title={"Số TRF"}
/>
</View>
<Text style={{ marginHorizontal: 15, color: R.colors.black }}>
nh chng ch <Text style={{ color: "red" }}>*</Text>
</Text>
<CardButtonImage />
<View style={styles.footer}>
<CheckBox
value={isSelected}
onValueChange={setSelection}
borderRadius={10}
marginLeft={15}
/>
<Text style={styles.text_footer}>
"Tôi xin cam đoan rằng chứng chỉ mà tôi đã nộp là chứng chỉ hoàn
toàn hợp lệ và có giá trị pháp lý. Nếu phát hiện bất kỳ sai phạm
nào liên quan đến tính xác thực của chứng chỉ, tôi xin hoàn toàn
chịu trách nhiệm và chấp nhận mọi hình thức xử lý theo quy định,
bao gồm cả việc bị buộc thôi học và cấm thi vào trường Đại học
Công nghệ Thông tin (UIT) trong thời hạn 5 năm."
</Text>
</View>
<Button
title="Thanh toán"
marginHorizontal={15}
fontSize={R.fontsize.fontSizeContent}
fontWeight={300}
fontFamily={R.fonts.InterRegular}
textStyle={styles.text_button}
backgroundColor={R.colors.buttonColorSel}
textColor={R.colors.white}
borderRadius={10}
paddingVertical={4}
/>
</View>
</ScrollView>
);
};
export default CertificateRegistrationView;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: R.colors.white,
},
container_row: {
flexDirection: 'row'
},
container_row_body: {
marginHorizontal: 15,
},
footer: {
flexDirection: "row",
marginBottom: 84,
marginRight: 15
},
text_footer: {
marginLeft: 10,
flex: 1,
fontFamily: R.fonts.InterRegular,
fontSize: R.fontsize.fontsSize12,
color: R.colors.black,
fontWeight: '400'
}
});
import React from 'react';
import {Text, View, StyleSheet} from 'react-native';
import DetailClassScheduleView from './view';
const DetailClassSchedule = (props) => {
return (
<DetailClassScheduleView />
);
};
export default DetailClassSchedule;
import React from 'react';
import { Text, View, TouchableOpacity, StyleSheet, ImageBackground } from 'react-native';
import R from '../../../assets/R';
import { useNavigation } from '@react-navigation/native';
const DetailClassScheduleView = (props) => {
const { } = props;
const ArrowLeftIcon = R.images.icBack;
const navigate = useNavigation();
return (
<SafeAreaView
style={styles.container}>
<ImageBackground
source={R.images.igBackgroundSlider}
style={styles.background_header}
>
<TouchableOpacity style={styles.back_button} onPress={() => navigate.goBack()}>
<ArrowLeftIcon
/>
</TouchableOpacity>
</ImageBackground>
<View style={styles.container_content}>
<Text style={styles.text_title}>Lch dy lp IT0032.47.T1</Text>
<Text style={styles.text_content}>Th 6: 25/07/2025, 07:00 - 09:00</Text>
<View style={[styles.container_content, { paddingHorizontal: 15, paddingVertical: 5 }]}>
<Text style={styles.text_content}>V trí: Phòng B205</Text>
<Text style={styles.text_content}>Sĩ s: 40</Text>
<Text style={styles.text_content}>Lp hc: Thc hành</Text>
<Text style={styles.text_content}>Hình thc hc: Trc tiếp</Text>
</View>
</View>
</SafeAreaView>
);
};
export default DetailClassScheduleView;
const styles = StyleSheet.create({
container: {
flex: 1,
},
back_button: {
position: 'absolute',
top: 20,
left: 15,
},
background_header: {
width: '100%',
height: 178,
},
text_title: {
fontSize: R.fontsize.fontsSize18,
fontWeight: '500',
fontFamily: R.fonts.InterRegular,
color: R.colors.blue500,
},
container_content: {
padding: 15,
},
text_content: {
fontSize: R.fontsize.fontsSize12,
fontWeight: '500',
fontFamily: R.fonts.InterSemiBold,
color: R.colors.black,
},
})
\ No newline at end of file
import React from 'react';
import {Text, View, StyleSheet} from 'react-native';
import Filter3DateView from './view';
const Filter3Date = (props) => {
return (
<Filter3DateView />
);
};
export default Filter3Date;
import React, {useState, useRef, useEffect} from 'react';
import {DeviceEventEmitter, PanResponder} from 'react-native';
import FilterDateView from './view';
const FilterDate = ({navigation}) => {
const [currentDate, setCurrentDate] = useState(new Date(2025, 6, 24));
const [selectedDate, setSelectedDate] = useState(new Date(2025, 6, 24));
const [showMonthPicker, setShowMonthPicker] = useState(false);
const scrollViewRef = useRef(null);
useEffect(() => {
DeviceEventEmitter.emit('onDateChange', selectedDate);
}, [selectedDate]);
const createMockEvents = () => {
return [
{
id: '1',
title: 'Lịch vào trực lớp TTCĐT 445.T1',
subtitle: 'CS Địa lý 4D',
time: '07:00',
endTime: '09:00',
date: '2025-07-24',
type: 'class',
},
{
id: '2',
title: 'Meeting team development',
subtitle: 'Phòng họp A1',
time: '10:00',
endTime: '11:30',
date: '2025-07-24',
type: 'meeting',
},
{
id: '3',
title: 'Training React Native',
subtitle: 'Online Zoom',
time: '14:00',
endTime: '16:00',
date: '2025-07-25',
type: 'training',
},
];
};
const mockEvents = createMockEvents();
const formatDateToString = (date) => {
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
return `${year}-${month}-${day}`;
};
const getEventsForDate = (date) => {
const dateStr = formatDateToString(date);
return mockEvents.filter(event => event.date === dateStr);
};
const getDayName = (date) => {
const days = ['Chủ nhật', 'Thứ 2', 'Thứ 3', 'Thứ 4', 'Thứ 5', 'Thứ 6', 'Thứ 7'];
return days[date.getDay()];
};
const getMonthName = (monthIndex) => {
const months = [
'Tháng 1', 'Tháng 2', 'Tháng 3', 'Tháng 4', 'Tháng 5', 'Tháng 6',
'Tháng 7', 'Tháng 8', 'Tháng 9', 'Tháng 10', 'Tháng 11', 'Tháng 12',
];
return months[monthIndex];
};
const handleMonthSelect = (monthIndex) => {
const newDate = new Date(currentDate);
newDate.setMonth(monthIndex);
setCurrentDate(newDate);
setSelectedDate(newDate);
setShowMonthPicker(false);
DeviceEventEmitter.emit('onDateChange', newDate);
};
const swipeToNextDay = () => {
const nextDay = new Date(selectedDate);
nextDay.setDate(selectedDate.getDate() + 1);
setSelectedDate(nextDay);
setCurrentDate(nextDay);
DeviceEventEmitter.emit('onDateChange', nextDay);
};
const swipeToPrevDay = () => {
const prevDay = new Date(selectedDate);
prevDay.setDate(selectedDate.getDate() - 1);
setSelectedDate(prevDay);
setCurrentDate(prevDay);
DeviceEventEmitter.emit('onDateChange', prevDay);
};
const toggleMonthPicker = () => {
setShowMonthPicker(!showMonthPicker);
};
const panResponder = PanResponder.create({
onMoveShouldSetPanResponder: (evt, gestureState) => {
return Math.abs(gestureState.dx) > 30 && Math.abs(gestureState.dy) < 100;
},
onPanResponderMove: (evt, gestureState) => {},
onPanResponderRelease: (evt, gestureState) => {
if (gestureState.dx > 50) {
swipeToPrevDay();
} else if (gestureState.dx < -50) {
swipeToNextDay();
}
},
});
const calculateEventPosition = (startTime, endTime) => {
const [startHour, startMinute] = startTime.split(':').map(Number);
const [endHour, endMinute] = endTime.split(':').map(Number);
const startTotalMinutes = startHour * 60 + startMinute;
const endTotalMinutes = endHour * 60 + endMinute;
const durationMinutes = endTotalMinutes - startTotalMinutes;
const HOUR_HEIGHT = 80;
const topPosition = (startTotalMinutes / 60) * HOUR_HEIGHT;
const height = (durationMinutes / 60) * HOUR_HEIGHT;
return { topPosition, height };
};
return (
<FilterDateView
navigation={navigation}
currentDate={currentDate}
selectedDate={selectedDate}
showMonthPicker={showMonthPicker}
scrollViewRef={scrollViewRef}
panResponder={panResponder}
getEventsForDate={getEventsForDate}
getDayName={getDayName}
getMonthName={getMonthName}
handleMonthSelect={handleMonthSelect}
toggleMonthPicker={toggleMonthPicker}
calculateEventPosition={calculateEventPosition}
/>
);
};
export default FilterDate;
\ No newline at end of file
import React from 'react';
import {
View,
Text,
TouchableOpacity,
ScrollView,
StyleSheet,
Dimensions,
SafeAreaView,
} from 'react-native';
import R from '../../../assets/R';
const {width: screenWidth, height: screenHeight} = Dimensions.get('window');
const HOUR_HEIGHT = 80;
const FilterDateView= ({
navigation,
currentDate,
selectedDate,
showMonthPicker,
scrollViewRef,
panResponder,
getEventsForDate,
getDayName,
getMonthName,
handleMonthSelect,
toggleMonthPicker,
calculateEventPosition,
}) => {
const renderMonthPicker = () => {
if (!showMonthPicker) return null;
return (
<View style={styles.monthPickerContainer}>
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={styles.monthPickerContent}>
{Array.from({length: 12}, (_, index) => (
<TouchableOpacity
key={index}
style={[
styles.monthItem,
currentDate.getMonth() === index && styles.monthItemSelected,
]}
onPress={() => handleMonthSelect(index)}>
<Text
style={[
styles.monthItemText,
currentDate.getMonth() === index && styles.monthItemTextSelected,
]}>
{getMonthName(index)}
</Text>
</TouchableOpacity>
))}
</ScrollView>
</View>
);
};
const renderDateInfo = () => {
return (
<View style={{backgroundColor: R.colors.grey_200}}>
<View style={styles.dateInfoContainer}>
<Text style={styles.dayName}>{getDayName(selectedDate)}</Text>
<Text style={styles.dayNumber}>{selectedDate.getDate()}</Text>
</View>
</View>
);
};
const renderTimeSlots = () => {
const hours = Array.from({length: 24}, (_, i) => i);
const selectedEvents = getEventsForDate(selectedDate);
return (
<View style={styles.timeSlotsContainer} {...panResponder.panHandlers}>
<ScrollView
ref={scrollViewRef}
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.scrollContent}>
<View style={styles.timelineContainer}>
<View style={styles.timeLabelsColumn}>
{hours.map((hour) => {
const timeStr = hour.toString().padStart(2, '0') + ':00';
return (
<View key={hour} style={styles.timeSlot}>
<Text style={styles.timeText}>{timeStr}</Text>
</View>
);
})}
</View>
<View style={styles.eventsColumn}>
{hours.map((hour) => (
<View key={hour} style={styles.gridLine} />
))}
{selectedEvents.map((event) => {
const { topPosition, height } = calculateEventPosition(event.time, event.endTime);
return (
<TouchableOpacity
key={event.id}
style={[
styles.eventCard,
{
position: 'absolute',
top: topPosition,
height: Math.max(height, 40),
left: 5,
right: 15,
zIndex: 10,
backgroundColor: R.colors.main,
}
]}
activeOpacity={0.7}>
<Text style={styles.eventTitle} numberOfLines={height > 60 ? 2 : 1}>
{event.title}
</Text>
{height > 40 && (
<Text style={styles.eventSubtitle} numberOfLines={1}>
{event.subtitle}
</Text>
)}
<Text style={styles.eventTime}>
{event.time} - {event.endTime}
</Text>
</TouchableOpacity>
);
})}
</View>
</View>
</ScrollView>
</View>
);
};
return (
<SafeAreaView style={styles.container}>
{renderMonthPicker()}
{renderDateInfo()}
{renderTimeSlots()}
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: R.colors.white,
},
monthPickerContainer: {
backgroundColor: R.colors.white,
borderBottomWidth: 1,
borderBottomColor: R.colors.grey_200,
paddingVertical: 10,
},
monthPickerContent: {
paddingHorizontal: 15,
},
monthItem: {
paddingHorizontal: 20,
paddingVertical: 8,
marginRight: 10,
borderRadius: 20,
backgroundColor: R.colors.grey_50,
},
dateInfoContainer: {
paddingHorizontal: 15,
paddingVertical: 12,
alignItems: 'center',
justifyContent:'center',
maxWidth:70,
borderRightWidth:1,
borderRightColor:R.colors.grey_200,
},
dayName: {
fontSize: R.fontsize.fontsSize12,
fontFamily: R.fonts.InterRegular,
color: R.colors.black,
marginBottom: 2,
},
dayNumber: {
fontSize: R.fontsize.fontsSize14,
fontFamily: R.fonts.InterSemiBold,
color: R.colors.blue500,
},
timeSlotsContainer: {
flex: 1,
backgroundColor: R.colors.white,
},
scrollContent: {
paddingBottom: 50,
},
timelineContainer: {
flexDirection: 'row',
position: 'relative',
},
timeLabelsColumn: {
minWidth: 70,
borderRightWidth: 1,
borderRightColor: R.colors.grey_200,
},
eventsColumn: {
flex: 1,
position: 'relative',
minHeight: 24 * HOUR_HEIGHT,
},
timeSlot: {
height: HOUR_HEIGHT,
alignItems: 'center',
justifyContent: 'center',
borderBottomWidth: 1,
borderBottomColor: R.colors.grey_100,
},
gridLine: {
height: HOUR_HEIGHT,
borderBottomWidth: 1,
borderBottomColor: R.colors.grey_100,
width: '100%',
},
timeText: {
fontSize: R.fontsize.fontsSize12,
fontFamily: R.fonts.InterRegular,
color: R.colors.black,
},
eventCard: {
borderRadius: 15,
paddingLeft: 15,
paddingTop: 10,
},
eventTitle: {
fontSize: R.fontsize.fontsSize12,
fontFamily: R.fonts.InterRegular,
color: R.colors.white,
fontWeight: '400',
marginBottom: 5,
},
eventSubtitle: {
fontSize: R.fontsize.fontsSize10,
fontFamily: R.fonts.InterRegular,
fontWeight: '400',
color: R.colors.white,
marginBottom: 5,
},
eventTime: {
fontSize: R.fontsize.fontsSize10,
fontFamily: R.fonts.InterRegular,
color: R.colors.white,
fontWeight: '400',
},
});
export default FilterDateView
\ No newline at end of file
import React from 'react';
import {Text, View, StyleSheet} from 'react-native';
import FilterWeekView from './view';
const FilterWeek = (props) => {
return (
<FilterWeekView />
);
};
export default FilterWeek;
import React, {useState, useMemo, useRef} from 'react';
import {Animated, PanResponder, Dimensions} from 'react-native';
import ClassScheduleView from './view';
const {height: screenHeight} = Dimensions.get('window');
const BOTTOM_SHEET_HEIGHT = screenHeight * 0.6;
const ClassSchedule = ({events = [], onDateSelect, onEventPress}) => {
const [currentDate, setCurrentDate] = useState(new Date(2025, 7, 1));
const [selectedDate, setSelectedDate] = useState(null);
const [showBottomSheet, setShowBottomSheet] = useState(false);
const bottomSheetTranslateY = useRef(new Animated.Value(BOTTOM_SHEET_HEIGHT)).current;
const formatDateToString = (date) => {
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
return `${year}-${month}-${day}`;
};
const createMockEvents = () => {
const today = new Date();
const todayStr = formatDateToString(today);
const tomorrow = new Date(today);
tomorrow.setDate(tomorrow.getDate() + 1);
const tomorrowStr = formatDateToString(tomorrow);
return [
{
id: '1',
title: 'Meeting hôm nay',
date: todayStr,
time: '10:00',
endTime: '11:00',
description: 'Họp team development',
type: 'meeting',
},
{
id: '2',
title: 'Demo hôm nay',
date: todayStr,
time: '15:00',
endTime: '16:00',
description: 'Present tính năng mới',
type: 'demo',
},
{
id: '11',
title: 'Lịch học lớp IT47.8F7',
date: '2025-08-04',
time: '07:00',
endTime: '08:30',
description: 'Môn học chuyên ngành',
type: 'class',
},
{
id: '12',
title: 'Meeting team',
date: '2025-08-04',
time: '10:00',
endTime: '11:00',
description: 'Họp team development',
type: 'meeting',
},
{
id: '13',
title: 'Training React Native',
date: '2025-08-05',
time: '14:00',
endTime: '16:00',
description: 'Học New Architecture',
type: 'training',
},
{
id: '14',
title: 'Code Review',
date: '2025-08-05',
time: '10:30',
endTime: '11:30',
description: 'Review PR #123',
type: 'review',
},
{
id: '15',
title: 'Họp nội bộ giữa giảng viên bộ môn công nghệ phần mềm',
date: '2025-08-05',
time: '09:00',
endTime: '11:30',
description: 'Thảo luận chương trình đào tạo mới',
type: 'meeting',
},
{
id: '16',
title: 'Sự kiện thắp sáng ước mơ kỹ thuật',
date: '2025-08-05',
time: '13:00',
endTime: '15:30',
description: 'Chương trình định hướng nghề nghiệp cho sinh viên',
type: 'event',
},
{
id: '17',
title: 'Lịch học lớp EWC45.364.L1',
date: '2025-08-05',
time: '14:00',
endTime: '15:30',
description: 'Tiếng Anh chuyên ngành',
type: 'class',
},
{
id: '18',
title: 'Họp tổng kết quả chấm nghiệm cứu khoa học sinh viên khóa K18',
date: '2025-08-05',
time: '17:00',
endTime: '20:30',
description: 'Đánh giá kết quả nghiên cứu khoa học của sinh viên',
type: 'meeting',
},
{
id: '3',
title: 'Training React Native',
date: tomorrowStr,
time: '14:00',
endTime: '16:00',
description: 'Học New Architecture',
type: 'training',
},
{
id: '4',
title: 'Code Review',
date: tomorrowStr,
time: '10:30',
endTime: '11:30',
description: 'Review PR #123',
type: 'review',
},
{
id: '10',
title: 'Demo sản phẩm',
date: '2025-08-25',
time: '15:00',
endTime: '16:30',
description: 'Present tính năng mới',
type: 'demo',
},
];
};
const mockEvents = createMockEvents();
const allEvents = [...events, ...mockEvents];
const panResponder = useRef(
PanResponder.create({
onMoveShouldSetPanResponder: (evt, gestureState) => {
return Math.abs(gestureState.dy) > 10;
},
onPanResponderMove: (evt, gestureState) => {
if (gestureState.dy > 0) {
bottomSheetTranslateY.setValue(gestureState.dy);
}
},
onPanResponderRelease: (evt, gestureState) => {
if (gestureState.dy > 100) {
hideBottomSheetModal();
} else {
Animated.spring(bottomSheetTranslateY, {
toValue: 0,
useNativeDriver: true,
}).start();
}
},
})
).current;
const getMonthData = useMemo(() => {
const year = currentDate.getFullYear();
const month = currentDate.getMonth();
const firstDay = new Date(year, month, 1);
const lastDay = new Date(year, month + 1, 0);
const startDate = new Date(firstDay);
startDate.setDate(firstDay.getDate() - firstDay.getDay());
const days = [];
const currentDateObj = new Date(startDate);
for (let i = 0; i < 42; i++) {
days.push(new Date(currentDateObj));
currentDateObj.setDate(currentDateObj.getDate() + 1);
}
return {
year,
month,
firstDay,
lastDay,
days,
};
}, [currentDate]);
const getEventsForDate = (date) => {
const dateStr = formatDateToString(date);
return allEvents.filter(event => event.date === dateStr);
};
const parseLocalDate = (dateString) => {
const [year, month, day] = dateString.split('-').map(Number);
return new Date(year, month - 1, day);
};
const formatDateToDisplay = (date) => {
const day = date.getDate().toString().padStart(2, '0');
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const year = date.getFullYear();
return `Lịch ngày ${day}/${month}/${year}`;
};
const isCurrentMonth = (date) => {
return date.getMonth() === currentDate.getMonth();
};
const isToday = (date) => {
const today = new Date();
return (
date.getDate() === today.getDate() &&
date.getMonth() === today.getMonth() &&
date.getFullYear() === today.getFullYear()
);
};
const navigateMonth = (direction) => {
const newDate = new Date(currentDate);
if (direction === 'prev') {
newDate.setMonth(newDate.getMonth() - 1);
} else {
newDate.setMonth(newDate.getMonth() + 1);
}
setCurrentDate(newDate);
setSelectedDate(null);
if (showBottomSheet) {
hideBottomSheetModal();
}
};
const showBottomSheetModal = () => {
setShowBottomSheet(true);
Animated.spring(bottomSheetTranslateY, {
toValue: 0,
tension: 100,
friction: 8,
useNativeDriver: true,
}).start();
};
const hideBottomSheetModal = () => {
Animated.timing(bottomSheetTranslateY, {
toValue: BOTTOM_SHEET_HEIGHT,
duration: 300,
useNativeDriver: true,
}).start(() => {
setShowBottomSheet(false);
});
};
const handleDatePress = (date) => {
const dateStr = formatDateToString(date);
const dayEvents = getEventsForDate(date);
setSelectedDate(dateStr);
onDateSelect?.(dateStr);
if (dayEvents.length > 0) {
showBottomSheetModal();
}
};
const handleEventPress = (event) => {
onEventPress?.(event);
};
const handleCloseBottomSheet = () => {
hideBottomSheetModal();
};
const getSelectedEvents = () => {
if (!selectedDate) return [];
return allEvents
.filter(event => event.date === selectedDate)
.sort((a, b) => a.time.localeCompare(b.time));
};
return (
<ClassScheduleView
currentDate={currentDate}
selectedDate={selectedDate}
showBottomSheet={showBottomSheet}
bottomSheetTranslateY={bottomSheetTranslateY}
panResponder={panResponder}
getMonthData={getMonthData}
getEventsForDate={getEventsForDate}
parseLocalDate={parseLocalDate}
formatDateToDisplay={formatDateToDisplay}
isCurrentMonth={isCurrentMonth}
isToday={isToday}
navigateMonth={navigateMonth}
handleDatePress={handleDatePress}
handleEventPress={handleEventPress}
handleCloseBottomSheet={handleCloseBottomSheet}
getSelectedEvents={getSelectedEvents}
/>
);
};
export default ClassSchedule;
\ No newline at end of file
import {StyleSheet, Dimensions} from 'react-native';
import R from '../../assets/R';
const {width: screenWidth, height: screenHeight} = Dimensions.get('window');
const CELL_WIDTH = (screenWidth - 30) / 7;
const CELL_HEIGHT = (screenHeight - 140) / 6;
const BOTTOM_SHEET_HEIGHT = screenHeight * 0.6;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: R.colors.white,
alignItems: 'center',
},
header: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingVertical: 15,
},
header_title: {
fontSize: R.fontsize.fontsSize16,
fontFamily: R.fonts.InterMedium,
color: R.colors.black,
fontWeight: '600',
},
navButton: {
width: 30,
height: 30,
borderRadius: 20,
backgroundColor: R.colors.blue500,
alignItems: 'center',
justifyContent: 'center',
},
navButtonText: {
color: R.colors.white,
fontSize: R.fontsize.fontsSize16,
fontFamily: R.fonts.InterMedium,
},
weekDaysContainer: {
flexDirection: 'row',
paddingBottom: 5,
marginBottom: 5,
},
weekDayCell: {
width: CELL_WIDTH,
alignItems: 'center',
},
weekDayText: {
fontFamily: R.fonts.InterRegular,
fontSize: R.fontsize.fontsSize10,
fontWeight: '400',
color: R.colors.black,
},
calendarGrid: {
},
weekRow: {
flexDirection: 'row',
},
dayCell: {
width: CELL_WIDTH,
minHeight: CELL_HEIGHT,
borderWidth: 1,
borderColor: R.colors.grey_200,
padding: 4,
alignItems: 'center',
},
selectedDayCell: {
borderColor: R.colors.blue500,
borderWidth: 1,
},
dayText: {
fontSize: R.fontsize.fontsSize12,
fontWeight: '500',
fontFamily:R.fonts.InterMedium,
color: R.colors.black,
marginBottom: 2,
},
dayTextInactive: {
color: R.colors.grey_100,
opacity: 1,
},
selectedDayText: {
color: R.colors.black,
fontWeight: 'bold',
fontFamily: R.fonts.InterSemiBold,
},
todayText: {
color: R.colors.white,
fontWeight: 'bold',
fontFamily: R.fonts.InterSemiBold,
backgroundColor: R.colors.blue500,
borderRadius: 10,
paddingHorizontal: 5,
},
eventsContainer: {
width: '100%',
flex: 1,
},
eventBar: {
paddingVertical: 2,
paddingHorizontal: 5,
borderRadius: 5,
marginBottom: 2,
},
eventBarText: {
fontSize: R.fontsize.fontsSize10,
color: R.colors.white,
fontWeight: '500',
fontFamily: R.fonts.InterRegular
},
moreEventsText: {
fontSize: R.fontsize.fontsSize10,
color: R.colors.grey_100,
textAlign: 'center',
},
modalBackdrop: {
flex: 1,
backgroundColor: R.colors.grey_200,
justifyContent: 'flex-end',
},
bottomSheet: {
height: BOTTOM_SHEET_HEIGHT,
backgroundColor: R.colors.white,
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
},
bottomSheetContent: {
paddingHorizontal: 15,
},
dragHandle: {
width: 40,
height: 4,
backgroundColor: R.colors.grey_200,
borderRadius: 2,
alignSelf: 'center',
marginTop: 10,
marginBottom: 15,
},
bottomSheetHeader: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
marginBottom: 20,
},
bottomSheetTitle: {
fontSize: R.fontsize.fontSizeHeader1,
fontFamily: R.fonts.InterMedium,
color: R.colors.black,
flex: 1,
},
closeButton: {
width: 30,
height: 30,
borderRadius: 15,
backgroundColor: R.colors.grey_200,
alignItems: 'center',
justifyContent: 'center',
},
closeButtonText: {
fontSize: R.fontsize.fontsSize12,
color: R.colors.grey_800,
fontFamily: R.fonts.InterRegular,
},
noEventsContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
paddingVertical: 40,
},
noEventsText: {
fontSize: R.fontsize.fontsSize12,
fontFamily: R.fonts.InterRegular,
color: R.colors.grey_800,
fontWeight: '400'
},
eventCard: {
flexDirection: 'row',
backgroundColor: R.colors.white,
borderRadius: 12,
padding: 15,
marginBottom: 12,
borderLeftWidth: 4,
borderLeftColor: R.colors.blue500,
shadowColor: R.colors.black,
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 1,
shadowRadius: 1,
elevation: 2,
},
eventTimeContainer: {
minWidth: 80,
alignItems: 'flex-start',
justifyContent: 'flex-start',
marginRight: 15,
},
eventTime: {
fontSize: R.fontsize.fontsSize12,
fontFamily: R.fonts.InterMedium,
color: R.colors.blue500,
fontWeight: '600',
},
eventContent: {
flex: 1,
},
eventTitle: {
fontSize: R.fontsize.fontsSize12,
fontFamily: R.fonts.InterMedium,
color: R.colors.black,
fontWeight: '600',
marginBottom: 4,
},
eventDescription: {
fontSize: R.fontsize.fontsSize12,
fontFamily: R.fonts.InterRegular,
color: R.colors.grey_800,
},
});
export {styles, CELL_WIDTH, BOTTOM_SHEET_HEIGHT};
import React from 'react';
import {
Text,
View,
TouchableOpacity,
StyleSheet,
ScrollView,
Dimensions,
Modal,
Animated,
SafeAreaView,
} from 'react-native';
import R from '../../assets/R';
import { styles, CELL_WIDTH, BOTTOM_SHEET_HEIGHT } from './style';
import { useNavigation } from '@react-navigation/native';
import * as SCREENNAME from '../../routers/ScreenNames';
const ClassScheduleView = ({
currentDate,
selectedDate,
showBottomSheet,
bottomSheetTranslateY,
panResponder,
getMonthData,
getEventsForDate,
parseLocalDate,
formatDateToDisplay,
isCurrentMonth,
isToday,
navigateMonth,
handleDatePress,
handleEventPress,
handleCloseBottomSheet,
getSelectedEvents,
}) => {
const navigation = useNavigation();
const renderHeader = () => {
const monthNames = [
'Tháng 1', 'Tháng 2', 'Tháng 3', 'Tháng 4', 'Tháng 5', 'Tháng 6',
'Tháng 7', 'Tháng 8', 'Tháng 9', 'Tháng 10', 'Tháng 11', 'Tháng 12',
];
return (
<View style={styles.header}>
<TouchableOpacity
style={styles.navButton}
onPress={() => navigateMonth('prev')}>
<Text style={styles.navButtonText}></Text>
</TouchableOpacity>
<Text style={styles.header_title}>
{monthNames[getMonthData.month]} {getMonthData.year}
</Text>
<TouchableOpacity
style={styles.navButton}
onPress={() => navigateMonth('next')}>
<Text style={styles.navButtonText}></Text>
</TouchableOpacity>
</View>
);
};
const renderWeekDays = () => {
const weekDays = ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'];
return (
<View style={styles.weekDaysContainer}>
{weekDays.map((day, index) => (
<View key={index} style={styles.weekDayCell}>
<Text style={styles.weekDayText}>{day}</Text>
</View>
))}
</View>
);
};
const renderDayCell = (date, index) => {
const dayEvents = getEventsForDate(date);
const isSelected = selectedDate === formatDateToString(date);
const isTodayDate = isToday(date);
const isInCurrentMonth = isCurrentMonth(date);
return (
<TouchableOpacity
key={index}
style={[
styles.dayCell,
isSelected && styles.selectedDayCell,
isTodayDate && styles.todayCell,
]}
onPress={() => handleDatePress(date)}
activeOpacity={0.7}>
<Text
style={[
styles.dayText,
!isInCurrentMonth && styles.dayTextInactive,
isSelected && styles.selectedDayText,
isTodayDate && styles.todayText,
]}>
{date.getDate()}
</Text>
{dayEvents.length > 0 && (
<View style={styles.eventsContainer}>
{dayEvents.slice(0, 2).map((event, eventIndex) => (
<TouchableOpacity
key={event.id}
style={[
styles.eventBar,
{ backgroundColor: R.colors.main },
]}
onPress={() => handleEventPress(event)}>
<Text style={styles.eventBarText} numberOfLines={1}>
{event.title}
</Text>
</TouchableOpacity>
))}
{dayEvents.length > 2 && (
<Text style={styles.moreEventsText}>+{dayEvents.length - 2}</Text>
)}
</View>
)}
</TouchableOpacity>
);
};
const formatDateToString = (date) => {
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
return `${year}-${month}-${day}`;
};
const renderCalendarGrid = () => {
const weeks = [];
for (let i = 0; i < 6; i++) {
const week = getMonthData.days.slice(i * 7, (i + 1) * 7);
weeks.push(
<View key={i} style={styles.weekRow}>
{week.map((date, dayIndex) =>
renderDayCell(date, i * 7 + dayIndex),
)}
</View>,
);
}
return <View style={styles.calendarGrid}>{weeks}</View>;
};
const renderBottomSheetContent = () => {
if (!selectedDate) return null;
const selectedDateObj = parseLocalDate(selectedDate);
const selectedEvents = getSelectedEvents();
return (
<View style={styles.bottomSheetContent}>
<View style={styles.dragHandle} />
<View style={styles.bottomSheetHeader}>
<Text style={styles.bottomSheetTitle}>
{formatDateToDisplay(selectedDateObj)}
</Text>
<TouchableOpacity
style={styles.closeButton}
onPress={handleCloseBottomSheet}>
<Text style={styles.closeButtonText}></Text>
</TouchableOpacity>
</View>
<ScrollView
style={styles.eventsScrollView}
showsVerticalScrollIndicator={false}>
{selectedEvents.length === 0 ? (
<View style={styles.noEventsContainer}>
<Text style={styles.noEventsText}>Không có s kin nào</Text>
</View>
) : (
selectedEvents.map((event, index) => (
<TouchableOpacity
key={event.id}
style={styles.eventCard}
onPress={() => navigation.navigate(SCREENNAME.DETAILCLASSSCHEDULE, { event })}
activeOpacity={0.7}>
<View style={styles.eventTimeContainer}>
<Text style={styles.eventTime}>
{event.time}
{event.endTime && ` - ${event.endTime}`}
</Text>
</View>
<View style={styles.eventContent}>
<Text style={styles.eventTitle} numberOfLines={2}>
{event.title}
</Text>
{event.description && (
<Text style={styles.eventDescription} numberOfLines={3}>
{event.description}
</Text>
)}
</View>
</TouchableOpacity>
))
)}
</ScrollView>
</View>
);
};
const renderBottomSheet = () => {
return (
<Modal
visible={showBottomSheet}
transparent={true}
animationType="none"
onRequestClose={handleCloseBottomSheet}>
<TouchableOpacity
style={styles.modalBackdrop}
activeOpacity={1}
onPress={handleCloseBottomSheet}>
<Animated.View
style={[
styles.bottomSheet,
{
transform: [{ translateY: bottomSheetTranslateY }],
},
]}
{...panResponder.panHandlers}>
<TouchableOpacity activeOpacity={1}>
{renderBottomSheetContent()}
</TouchableOpacity>
</Animated.View>
</TouchableOpacity>
</Modal>
);
};
return (
<SafeAreaView style={styles.container}>
<ScrollView showsVerticalScrollIndicator={false}>
{renderHeader()}
{renderWeekDays()}
{renderCalendarGrid()}
</ScrollView>
{renderBottomSheet()}
</SafeAreaView>
);
};
export default ClassScheduleView;
\ No newline at end of file
import React, { useState, useMemo } from "react";
import {
Text,
View,
StyleSheet,
Modal,
Pressable,
Image,
Touchable,
TouchableOpacity,
} from "react-native";
import DebtView from "./view";
import R from "../../assets/R";
const Debt = (props) => {
const [activeTab, setActiveTab] = useState("WFP");
const IconImage = R.images.icImage;
const [dataListStatus, setDataListStatus] = useState([
{ key: "WFP", title_status: "Chờ thanh toán" },
{ key: "P", title_status: "Đã thanh toán" },
{ key: "O", title_status: "Quá hạn" },
]);
const handleTabChange = (tabKey) => {
setActiveTab(tabKey);
};
const closeModal = () => {
setModalVisible(false);
};
const [dataListDebtItem, setDataListDebtItem] = useState([
{
id: 1,
title_notifi_student_code:
"Trường thông báo sinh viên 086592 cần thanh toán khoản công nợ thư viện",
price: 50000,
code_debt: "hfhfkYRBFI37457HDNNF",
type_debt: "Đã thanh toán",
message_debt: "Em cần thanh toán nợ từ việc làm mất sách của trường",
payment_term: "23/07/2025",
status: "P",
},
{
id: 2,
title_notifi_student_code:
"Trường thông báo sinh viên 086592 cần thanh toán khoản công nợ thư viện",
price: 50000,
code_debt: "hfhfkYRBFI37457HDNNF",
type_debt: "Nợ thư viện",
message_debt: "Em cần thanh toán nợ từ việc làm mất sách của trường",
payment_term: "23/07/2025",
status: "O",
},
{
id: 3,
title_notifi_student_code:
"Trường thông báo sinh viên 086592 cần thanh toán khoản công nợ thư viện",
price: 50000,
code_debt: "hfhfkYRBFI37457HDNNF",
type_debt: "Chờ thanh toán",
message_debt: "Em cần thanh toán nợ từ việc làm mất sách của trường",
payment_term: "23/07/2025",
status: "WFP",
},
{
id: 4,
title_notifi_student_code:
"Trường thông báo sinh viên 086592 cần thanh toán khoản công nợ thư viện",
price: 50000,
code_debt: "hfhfkYRBFI37457HDNNF",
type_debt: "Chờ thanh toán",
message_debt: "Em cần thanh toán nợ từ việc làm mất sách của trường",
payment_term: "23/07/2025",
status: "WFP",
},
{
id: 5,
title_notifi_student_code:
"Trường thông báo sinh viên 086592 cần thanh toán khoản công nợ thư viện",
price: 50000,
code_debt: "hfhfkYRBFI37457HDNNF",
type_debt: "Chờ thanh toán",
message_debt: "Em cần thanh toán nợ từ việc làm mất sách của trường",
payment_term: "23/07/2025",
status: "WFP",
},
{
id: 6,
title_notifi_student_code:
"Trường thông báo sinh viên 086592 cần thanh toán khoản công nợ thư viện",
price: 50000,
code_debt: "hfhfkYRBFI37457HDNNF",
type_debt: "Chờ thanh toán",
message_debt: "Em cần thanh toán nợ từ việc làm mất sách của trường",
payment_term: "23/07/2025",
status: "WFP",
},
]);
const [timeDebt, setTimeDebt] = useState("Hôm nay, 21/07/2025");
const getItemDisplayConfig = (status, type_debt) => {
switch (status) {
case "WFP": // Chờ thanh toán
return {
titleColor:
type_debt === "Nợ thư viện" ? R.colors.red : R.colors.black,
priceColor: R.colors.textSubMain,
timeColor: R.colors.red,
typeDebtColor: R.colors.black,
showButton: true,
showPaymentTerm: true,
};
case "P":
return {
titleColor: R.colors.black,
priceColor: R.colors.green,
timeColor: false,
typeDebtColor: R.colors.black,
showButton: false,
};
case "O": // Quá hạn
return {
titleColor: R.colors.red,
priceColor: R.colors.textSubMain,
timeColor: R.colors.red,
typeDebtColor: R.colors.black,
showButton: true,
showPaymentTerm: true,
};
}
};
const handlePayPress = (item) => {
setModalVisible(true);
console.log("Đã bấm Thanh toán:", item);
};
const [modalVisible, setModalVisible] = useState(false);
const processedDebtItems = useMemo(() => {
return dataListDebtItem.map((item) => {
const displayConfig = getItemDisplayConfig(item.status, item.type_debt);
return {
id: item.id,
title_notifi_student_code: item.title_notifi_student_code,
price: item.price,
code_debt: item.code_debt,
type_debt: item.type_debt,
message_debt: item.message_debt,
payment_term: item.payment_term,
status: item.status,
displayConfig: displayConfig,
};
});
}, [dataListDebtItem]);
return (
<>
<DebtView
onTabChange={handleTabChange}
activeTab={activeTab}
dataListStatus={dataListStatus}
dataListDebtItem={processedDebtItems}
timeDebt={timeDebt}
onPayPress={handlePayPress}
/>
<Modal
visible={modalVisible}
transparent
animationType="slide"
onRequestClose={() => setModalVisible(false)}
>
<Pressable
style={{
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "rgba(0, 0, 0, 0.55)",
}}
onPress={closeModal}
>
<View
style={{
padding: 20,
backgroundColor: "white",
borderRadius: 10,
}}
>
<Image
source={R.images.igQrCode}
style={{
width: 280,
height: 380,
resizeMode: "contain",
}}
/>
<TouchableOpacity
style={{ alignItems: "center", justifyContent: "center" }}
onPress={console.log("Nhấn để lưu ảnh")}
>
<IconImage></IconImage>
<Text
style={{
fontFamily: R.fonts.InterRegular,
fontWeight: "300",
fontSize: R.fontsize.fontSizeContent,
color: R.colors.txtMain,
}}
>
Lưu nh
</Text>
</TouchableOpacity>
</View>
</Pressable>
</Modal>
</>
);
};
export default Debt;
import { StyleSheet, Text, View } from "react-native";
import React from "react";
import { useNavigation } from "@react-navigation/native";
import R from "../../assets/R";
import Button from "../../components/Button";
const ItemList = ({ item , onPayPress}) => {
const navigate = useNavigation();
const QrCodeIconButton = R.images.icQrCodeButton;
const { displayConfig } = item;
return (
<View style={styles.container}>
<Text style={[styles.title, { color: displayConfig.titleColor }]}>
{item.title_notifi_student_code}
</Text>
<View style={styles.container_content}>
<Text style={styles.sub_title}>S tin: </Text>
<Text style={[styles.price_text, { color: displayConfig.priceColor }]}>
{item.price}
</Text>
</View>
<View style={styles.container_content}>
<Text style={styles.sub_title}>Mã công n: </Text>
<Text style={styles.code}>{item.code_debt}</Text>
</View>
<View style={styles.container_content}>
<Text style={styles.sub_title}>Loi công n: </Text>
<Text style={[styles.type_of_debt, { color: displayConfig.typeDebtColor }]}>
{item.type_debt}
</Text>
</View>
<View style={styles.container_content}>
<Text style={styles.sub_title}>Ghi chú: </Text>
<Text style={[{ flex: 1 }, styles.note]}>{item.message_debt}</Text>
</View>
<View style={styles.container_content}>
{displayConfig.showPaymentTerm && (
<View style={{flex:1, flexDirection:'row'}}>
<Text style={styles.sub_title}>Hn thanh toán: </Text>
<Text style={[styles.time, { color: displayConfig.timeColor }]}>
{item.payment_term}
</Text>
</View>
)}
{displayConfig.showButton && (
<View style={styles.container_button}>
<Button
marginRight={0}
title="Thanh toán"
textStyle={styles.text_button}
icon={(props) => <QrCodeIconButton width={16} height={16} />}
backgroundColor={R.colors.buttonColorSel}
textColor={R.colors.white}
justifyContent="center"
alignItems="center"
height={32}
borderRadius={8}
paddingHorizontal={12}
iconSpacingHorizontal={4}
onPress={() => onPayPress?.(item)}
/>
</View>
)}
</View>
</View>
);
};
export default ItemList;
const styles = StyleSheet.create({
container: {
backgroundColor: R.colors.backgroundCard,
marginHorizontal: 15,
marginVertical: 5,
borderRadius: 10,
paddingVertical: 9,
paddingHorizontal: 15,
},
title: {
color: R.colors.black,
fontSize: R.fontsize.fontsSize14,
fontFamily: R.fonts.InterMedium,
fontWeight:'500',
lineHeight: 24,
},
sub_title: {
color: R.colors.black,
fontSize: R.fontsize.fontsSize12,
fontWeight: "300",
lineHeight: 24,
fontFamily: R.fonts.InterRegular,
},
price_text: {
color: R.colors.blue500,
fontFamily: R.fonts.InterRegular,
fontWeight: "bold",
lineHeight: 24,
fontSize: R.fontsize.fontsSize12,
},
code: {
color: R.colors.black,
fontFamily: R.fonts.InterRegular,
fontWeight: "bold",
lineHeight: 24,
fontSize: R.fontsize.fontsSize12,
},
type_of_debt: {
color: R.colors.black,
fontFamily: R.fonts.InterRegular,
fontWeight: "bold",
lineHeight: 24,
fontSize: R.fontsize.fontsSize12,
},
note: {
color: R.colors.black,
fontFamily: R.fonts.InterRegular,
fontWeight: "400",
lineHeight: 24,
fontSize: R.fontsize.fontsSize12,
},
time: {
color: R.colors.red,
fontFamily: R.fonts.InterRegular,
fontWeight: "400",
lineHeight: 24,
fontSize: R.fontsize.fontsSize12,
},
container_content: {
flexDirection: "row",
},
container_button:{
},
text_button:{
fontFamily: R.fonts.InterRegular,
fontWeight: "400",
fontSize: R.fontsize.fontsSize12,
},
});
import React, { useState } from "react";
import {
Text,
SafeAreaView,
TouchableOpacity,
FlatList,
StyleSheet,
Modal,
View,
Image,
TextInput,
} from "react-native";
import Header from "../../components/Header/Header";
import I18n from "../../helper/i18/i18n";
import R from "../../assets/R";
import ItemList from "./item";
const DebtView = (props) => {
const { onTabChange, dataListStatus, dataListDebtItem, activeTab, timeDebt } =
props;
const IconSearch = R.images.icSearch
const renderTabViewItem = ({ item }) => {
const isActive = activeTab === item.key;
return (
<TouchableOpacity
style={[styles.tab_button, isActive && styles.tabButtonActive]}
onPress={() => onTabChange(item.key)}
>
<Text
style={[styles.tabButtonText, isActive && styles.tabButtonTextActive]}
>
{item.title_status}
</Text>
</TouchableOpacity>
);
};
const renderItem = ({ item }) => {
return <ItemList item={item} onPayPress={props.onPayPress} />;
};
const filteredDebtItems = dataListDebtItem.filter(
(item) => item.status === activeTab
);
return (
<SafeAreaView style={styles.container}>
<Header isBack title={I18n.t("Debt")} />
<View style={styles.tab_container}>
<FlatList
data={dataListStatus}
renderItem={renderTabViewItem}
keyExtractor={(item) => item.key}
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={styles.tab_scroll_content}
/>
</View>
<View style={{ marginHorizontal: 15, flexDirection: "row", alignItems: "center", borderWidth: 1, borderColor: R.colors.gray400, borderRadius: 50, padding: 0, maxHeight: 40, paddingHorizontal: 10, marginVertical: 5 }}>
<IconSearch width={20} height={20} stroke={R.colors.gray400}/>
<TextInput
placeholder={"Tìm kiếm"}
style={styles.input}
placeholderTextColor={R.colors.gray400}
/>
</View>
<Text style={styles.sub_text}>{props.timeDebt}</Text>
<FlatList
data={filteredDebtItems}
renderItem={renderItem}
showsVerticalScrollIndicator={false}
keyExtractor={(item) => item.id.toString()}
/>
</SafeAreaView>
);
};
export default DebtView;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: R.colors.white,
},
input: {
height: 40,
paddingHorizontal: 10,
fontFamily: R.fonts.InterRegular,
fontWeight: "400",
color: R.colors.gray400,
fontSize: R.fontsize.fontsSize12,
},
tab_container: {
marginHorizontal: 10,
justifyContent: "center",
},
tab_button: {
marginHorizontal: 5,
borderRadius: 15,
width:132,
backgroundColor: R.colors.gray400,
alignItems: "center",
justifyContent:"center"
},
tabButtonActive: {
backgroundColor: R.colors.blue500,
},
tabButtonText: {
fontFamily: R.fonts.InterSemiBold,
fontWeight: "600",
fontSize: R.fontsize.fontsSize12,
color: R.colors.white,
},
tabButtonTextActive: {
color: R.colors.white,
fontWeight: "600",
fontFamily: R.fonts.InterSemiBold,
fontSize: R.fontsize.fontsSize12,
},
tab_scroll_content: {
height: 28,
marginTop:5
},
sub_text: {
color: R.colors.black,
marginLeft: 15,
fontFamily: R.fonts.InterRegular,
fontWeight: "300",
fontSize: R.fontsize.fontsSize12,
},
});
import React from 'react';
import {Text, View} from 'react-native';
import ELearningView from './view';
const Elearning = ({props}) => <ELearningView />;
export default Elearning;
import React from 'react';
import {Text, View, TouchableOpacity} from 'react-native';
const ELearningView = ({props}) => (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}>
<TouchableOpacity>
<Text>ELearning</Text>
</TouchableOpacity>
</View>
);
export default ELearningView;
import React, { useState } from 'react';
import {Text, View, StyleSheet} from 'react-native';
import ExamScheduleView from './view';
const ExamSchedule = (props) => {
const [dataExamSchedule, setDataExamSchedule] = useState([
{
id: 1,
code_exam: 'MD001',
code_class:'MD0081',
poetry:'123 (7:30 - 10:30)',
time_exam:'2025-08-05',
class_exam:'A98',
day_exam:'Thứ 3',
description: 'Bảo vệ/ DA',
},
{
id: 2,
code_exam: 'MD001',
code_class:'MD0081',
poetry:'123 (7:30 - 10:30)',
time_exam:'2025-08-05',
class_exam:'A98',
day_exam:'Thứ 3',
description: 'Bảo vệ/ DA',
},
{
id: 3,
code_exam: 'MD001',
code_class:'MD0081',
poetry:'123 (7:30 - 10:30)',
time_exam:'2025-08-05',
class_exam:'A98',
day_exam:'Thứ 3',
description: 'Bảo vệ/ DA',
},
{
id: 4,
code_exam: 'MD001',
code_class:'MD0081',
poetry:'123 (7:30 - 10:30)',
time_exam:'2025-08-05',
class_exam:'A98',
day_exam:'Thứ 3',
description: 'Bảo vệ/ DA',
},
{
id: 5,
code_exam: 'MD001',
code_class:'MD0081',
poetry:'123 (7:30 - 10:30)',
time_exam:'2025-08-05',
class_exam:'A98',
day_exam:'Thứ 3',
description: 'Bảo vệ/ DA',
},
{
id: 6,
code_exam: 'MD001',
code_class:'MD0081',
poetry:'123 (7:30 - 10:30)',
time_exam:'2025-08-05',
class_exam:'A98',
day_exam:'Thứ 3',
description: 'Bảo vệ/ DA',
},
]);
return (
<ExamScheduleView dataExamSchedule={dataExamSchedule} />
);
};
export default ExamSchedule;
import R from "../../assets/R";
import { Text, View, TouchableOpacity, StyleSheet, Image } from 'react-native';
const ItemView = ({item}) => {
return (
<TouchableOpacity style={styles.container}>
<Text style={styles.text_title}>Mã môn hc: {item.code_exam}</Text>
<Text style={styles.text_title}>Mã lp: {item.code_class}</Text>
<View style={styles.content}>
<Text style={styles.text_content}>Ca/Tiết thi: {item.poetry}</Text>
<Text style={styles.text_content}>Th thi: {item.day_exam}</Text>
</View>
<View style={styles.content}>
<Text style={styles.text_content}>Ngày thi: {item.time_exam}</Text>
<Text style={styles.text_content}>Phòng thi: {item.class_exam}</Text>
</View>
<Text style={styles.text_content}>Ghi chú/ hình thc thi: {item.description}</Text>
</TouchableOpacity>
);
};
export default ItemView;
const styles = StyleSheet.create({
container: {
borderRadius: 10,
paddingHorizontal: 14,
paddingVertical: 10,
marginBottom: 10,
shadowColor: R.colors.black,
shadowOffset: {
width: 0,
},
shadowOpacity: 1,
shadowRadius: 5,
elevation: 5,
backgroundColor: R.colors.white,
marginVertical: 5,
marginHorizontal:10
},
content: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
text_title: {
fontSize: R.fontsize.fontsSize12,
fontWeight: '500',
color: R.colors.blue500,
fontFamily: R.fonts.InterSemiBold,
},
text_content: {
fontSize: R.fontsize.fontsSize12,
color: R.colors.black,
fontWeight: '400',
fontFamily: R.fonts.InterRegular,
},
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment