u
This commit is contained in:
1 parent
bde3487da3
commit
7a9a22e02e
9 files changed
+243
-60
No files matched your search
@@ -1,40 +1,85 @@
|
||||
import { DateRangePicker } from '@yz1311/react-native-wheel-picker'
|
||||
import React from 'react'
|
||||
import { Button, ButtonText } from '@/components/ui/button'
|
||||
import SegmentedControl from '@react-native-segmented-control/segmented-control'
|
||||
import React, { useState } from 'react'
|
||||
import { ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native'
|
||||
import { ATab } from '@/components/common/ao'
|
||||
|
||||
export default function DemoDatePickerUI() {
|
||||
const [index, setIndex] = useState(0)
|
||||
|
||||
export default function Example() {
|
||||
const [showDrawer, setShowDrawer] = React.useState(false)
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
onPress={() => {
|
||||
setShowDrawer(true)
|
||||
}}
|
||||
className="mt-10"
|
||||
>
|
||||
<ButtonText>Open Drawer</ButtonText>
|
||||
</Button>
|
||||
<View style={{ flex: 1, backgroundColor: '#f3f4f6', padding: 16 }}>
|
||||
{/* 快捷选项栏 */}
|
||||
<ScrollView horizontal showsHorizontalScrollIndicator={false} style={{ marginBottom: 12 }}>
|
||||
<ATab
|
||||
data={[
|
||||
{
|
||||
label: '不限',
|
||||
key: '不限',
|
||||
},
|
||||
{
|
||||
label: '今天',
|
||||
key: '今天',
|
||||
},
|
||||
{
|
||||
label: '本月',
|
||||
key: '本月',
|
||||
},
|
||||
{
|
||||
label: '本年',
|
||||
key: '本年',
|
||||
},
|
||||
|
||||
]}
|
||||
/>
|
||||
</ScrollView>
|
||||
|
||||
<DateRangePicker
|
||||
pickerTitle="预约时间"
|
||||
pickerCancelBtnText="取消"
|
||||
pickerConfirmBtnText="确认"
|
||||
// 开启modal模式
|
||||
isModal={true}
|
||||
// 可以自定义modal的一些属性
|
||||
modalProps={{
|
||||
|
||||
}}
|
||||
modalVisible={showDrawer}
|
||||
// modalVisible回调函数
|
||||
onModalVisibleChange={(visible) => {
|
||||
}}
|
||||
onPickerCancel={() => {
|
||||
}}
|
||||
onPickerConfirm={(date) => {
|
||||
setShowDrawer(false)
|
||||
}}
|
||||
{/* SegmentedControl */}
|
||||
<SegmentedControl
|
||||
values={['时间', '日', '月', '年', '范围']}
|
||||
selectedIndex={index}
|
||||
onChange={event => setIndex(event.nativeEvent.selectedSegmentIndex)}
|
||||
style={styles.segmentedControl}
|
||||
sliderStyle={styles.sliderStyle}
|
||||
/>
|
||||
</>
|
||||
|
||||
{/* 日期选择器占位 */}
|
||||
<View style={styles.datePickerPlaceholder}>
|
||||
<Text style={{ color: '#888' }}>这里显示日期选择器</Text>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
quickOption: {
|
||||
paddingVertical: 6,
|
||||
paddingHorizontal: 12,
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: 6,
|
||||
borderWidth: 1,
|
||||
borderColor: '#ccc',
|
||||
marginRight: 8,
|
||||
height: 32,
|
||||
},
|
||||
quickOptionText: {
|
||||
fontSize: 14,
|
||||
color: '#333',
|
||||
},
|
||||
segmentedControl: {
|
||||
borderRadius: 0,
|
||||
height: 36,
|
||||
backgroundColor: '#e5e7eb',
|
||||
marginBottom: 12,
|
||||
},
|
||||
sliderStyle: {
|
||||
borderRadius: 0,
|
||||
backgroundColor: '#2196f3',
|
||||
},
|
||||
datePickerPlaceholder: {
|
||||
height: 200,
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: 6,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
})
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { MoneyCategoryItem } from '@/types/money/category'
|
||||
import { useCallback, useEffect, useMemo, useRef } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { AInput, LucideIcon } from '@/components/common/ao'
|
||||
import EmptyState from '@/components/common/EmptyStatus'
|
||||
import {
|
||||
Actionsheet,
|
||||
ActionsheetBackdrop,
|
||||
@@ -34,6 +36,7 @@ export default function CategorySheet({
|
||||
}: CategorySheetProps) {
|
||||
const listRef = useRef<any>(null)
|
||||
const hasAutoScrolled = useRef(false)
|
||||
const [searchText, setSearchText] = useState('')
|
||||
|
||||
// 记住目标滚动位置
|
||||
const pendingScrollRef = useRef<{
|
||||
@@ -128,17 +131,45 @@ export default function CategorySheet({
|
||||
}
|
||||
}, [open, value, sections])
|
||||
|
||||
const filteredSections = useMemo<CategorySection[]>(() => {
|
||||
if (!searchText.trim()) {
|
||||
return sections
|
||||
}
|
||||
|
||||
const lower = searchText.trim().toLowerCase()
|
||||
|
||||
return sections.map(section => ({
|
||||
...section,
|
||||
data: section.data.filter(item =>
|
||||
item.name.toLowerCase().includes(lower),
|
||||
),
|
||||
})).filter(section => section.data.length > 0)
|
||||
}, [sections, searchText])
|
||||
|
||||
function handleClose() {
|
||||
onClose?.()
|
||||
setSearchText('')
|
||||
}
|
||||
|
||||
return (
|
||||
<Actionsheet isOpen={open} onClose={onClose}>
|
||||
<Actionsheet isOpen={open} onClose={handleClose}>
|
||||
<ActionsheetBackdrop />
|
||||
<ActionsheetContent style={{ maxHeight: '60%' }}>
|
||||
<ActionsheetContent style={{ maxHeight: '60%', minHeight: '60%' }}>
|
||||
<ActionsheetDragIndicatorWrapper>
|
||||
<ActionsheetDragIndicator />
|
||||
</ActionsheetDragIndicatorWrapper>
|
||||
|
||||
<AInput
|
||||
placeholder="请输入搜索关键词"
|
||||
className="mt-2"
|
||||
value={searchText}
|
||||
onChangeText={setSearchText}
|
||||
leftIcon={() => <LucideIcon icon="Search" size={16} color="#666" />}
|
||||
/>
|
||||
|
||||
<ActionsheetSectionList
|
||||
ref={listRef}
|
||||
sections={sections}
|
||||
sections={filteredSections}
|
||||
stickySectionHeadersEnabled={true}
|
||||
showsVerticalScrollIndicator={false}
|
||||
onEndReachedThreshold={0.1}
|
||||
@@ -177,7 +208,13 @@ export default function CategorySheet({
|
||||
const s = section as CategorySection
|
||||
|
||||
return (
|
||||
<ActionsheetSectionHeaderText className="font-semibold text-[black] text-sm bg-white">
|
||||
<ActionsheetSectionHeaderText
|
||||
className="font-semibold text-[black] text-sm bg-white"
|
||||
style={{
|
||||
paddingLeft: 0,
|
||||
paddingRight: 0,
|
||||
}}
|
||||
>
|
||||
{s.title}
|
||||
{' '}
|
||||
(
|
||||
@@ -187,6 +224,10 @@ export default function CategorySheet({
|
||||
)
|
||||
}}
|
||||
/>
|
||||
|
||||
{filteredSections.length === 0 && (
|
||||
<EmptyState title="空" />
|
||||
)}
|
||||
</ActionsheetContent>
|
||||
</Actionsheet>
|
||||
)
|
||||
|
||||
@@ -2,7 +2,6 @@ import type { AnalysisMoneyAmount } from '@/types/money/analysis'
|
||||
import dayjs from 'dayjs'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { ScrollView, Text, TouchableOpacity, View } from 'react-native'
|
||||
import Svg from 'react-native-svg'
|
||||
import { VictoryChart, VictoryLabel, VictoryLine, VictoryPie, VictoryTheme, VictoryTooltip } from 'victory-native'
|
||||
import { ADatePicker, ADateRangePicker, ASegmentedTabs, LucideIcon } from '@/components/common/ao'
|
||||
import EmptyState from '@/components/common/EmptyStatus'
|
||||
@@ -10,6 +9,7 @@ import CustomHeader from '@/components/custom/Header'
|
||||
import PagerTabs from '@/components/custom/PagerTabs'
|
||||
import { analysisMoneyLineApi, analysisMoneyPieApi } from '@/request/api/money/analysis'
|
||||
import { MoneyCategoryEnum } from '@/types/money/category'
|
||||
import { add } from '@/utils/math'
|
||||
import { getCurrentYear, getCurrentYearMonth, getEndOfMonth, getStartOfMonth } from '@/utils/time'
|
||||
|
||||
interface AnalysisContentProps {
|
||||
@@ -55,10 +55,6 @@ export default function Analysis() {
|
||||
periodType = 1
|
||||
}
|
||||
else {
|
||||
console.log(selectedStartDate.isSame(selectedEndDate, 'day'))
|
||||
console.log(selectedStartDate.isSame(selectedEndDate, 'month'))
|
||||
console.log(selectedStartDate.isSame(selectedEndDate, 'year'))
|
||||
|
||||
if (selectedStartDate.isSame(selectedEndDate, 'month')) {
|
||||
periodType = 0
|
||||
start = selectedStartDate.startOf('month').format('YYYY-MM-DD')
|
||||
@@ -98,6 +94,10 @@ export default function Analysis() {
|
||||
}
|
||||
})
|
||||
}
|
||||
const totalAmount: number = pieRecords.reduce(
|
||||
(sum, item) => Number(add(sum, Number(item.y) || 0)),
|
||||
0,
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
fetchChartsData()
|
||||
@@ -190,16 +190,24 @@ export default function Analysis() {
|
||||
</View>
|
||||
|
||||
<View className="mt-4" style={{ paddingBottom: 24 }}>
|
||||
<Text className="text-lg font-semibold text-gray-700">分类详细</Text>
|
||||
<View className="flex flex-row justify-between">
|
||||
<Text className="text-lg font-semibold text-gray-700">分类详细</Text>
|
||||
<Text>
|
||||
总:
|
||||
{totalAmount}
|
||||
{' '}
|
||||
元
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{
|
||||
pieRecords.length > 0
|
||||
? (
|
||||
<View className="mt-4 space-y-3">
|
||||
<View className="mt-4 flex flex-col gap-2">
|
||||
{pieRecords.map((item, index) => (
|
||||
<View
|
||||
key={index}
|
||||
className={`flex flex-row justify-between items-center p-3 bg-white shadow-md rounded-lg ${index !== pieRecords.length - 1 ? 'border-b border-gray-300' : ''}`}
|
||||
className="flex flex-row justify-between items-center py-3 border-b border-gray-300"
|
||||
>
|
||||
<Text className="text-base font-medium text-gray-800">{item.x}</Text>
|
||||
<Text className="text-base font-semibold text-gray-700">
|
||||
|
||||
Reference in new issue
Block a user