complated

This commit is contained in:
Samandar Turgunboyev
2026-02-17 10:46:57 +05:00
parent 754f11804a
commit d747c72c8d
71 changed files with 917 additions and 397 deletions

View File

@@ -5,6 +5,7 @@ import {
BottomSheetModal,
BottomSheetScrollView,
} from '@gorhom/bottom-sheet';
import { Image } from 'expo-image';
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
@@ -12,6 +13,7 @@ import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
export type Option = {
label: string;
value: string;
flag?: string;
};
type CategorySelectorProps = {
@@ -91,6 +93,12 @@ export default function CategorySelectorBottomSheet({
onClose();
}}
>
{item.flag ? (
<Image
source={{ uri: `https://flagcdn.com/24x18/${item.flag.toLowerCase()}.png` }}
style={{ width: 24, height: 18, borderRadius: 2 }}
/>
) : null}
<Text
style={[
styles.optionText,
@@ -129,6 +137,10 @@ const styles = StyleSheet.create({
paddingVertical: 16,
paddingHorizontal: 20,
borderBottomWidth: 1,
flexDirection: 'row',
alignContent: 'center',
alignItems: 'center',
gap: 10,
},
optionText: {
fontSize: 16,

View File

@@ -16,6 +16,7 @@ import {
View,
} from 'react-native';
import OneClick from '@/assets/images/one_click.png';
import PAYME from '@/assets/images/Payme_NEW.png';
import { useTranslation } from 'react-i18next';
import { price_calculation } from '../lib/api';
@@ -210,14 +211,13 @@ export default function CreateAdsScreens() {
style={[styles.safeArea, isDark ? styles.darkBg : styles.lightBg]}
>
<ScrollView contentContainerStyle={[styles.container, { paddingBottom: 90 }]}>
<Image
source={OneClick}
style={{ width: 180, height: 56, marginBottom: 10 }}
resizeMode="contain"
/>
<Text style={[styles.title, isDark ? styles.darkText : styles.lightText]}>
{currentStep === 1
? t("E'lon ma'lumotlari")
: currentStep === 2
? t('Sohalar')
: currentStep === 3
? t('Manzil')
: t("To'lov")}
{t("Bir Zumda Jonatish")}
</Text>
{currentStep === 1 && (
@@ -334,7 +334,7 @@ const styles = StyleSheet.create({
backgroundColor: '#f8fafc',
},
container: { padding: 20 },
title: { fontSize: 22, fontWeight: '800', marginBottom: 20 },
title: { fontSize: 18, fontWeight: '800', marginBottom: 20 },
darkText: {
color: '#f1f5f9',
},

View File

@@ -6,7 +6,6 @@ import React, { forwardRef, useCallback, useImperativeHandle, useState } from 'r
import { useTranslation } from 'react-i18next';
import { Image, StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native';
type MediaType = { uri: string; type: 'image' | 'video' };
type StepProps = { formData: any; updateForm: (key: string, value: any) => void };
type Errors = {
@@ -302,7 +301,7 @@ const styles = StyleSheet.create({
paddingHorizontal: 16,
height: 56,
},
textArea: { height: 120, alignItems: 'flex-start', paddingVertical: 12 },
textArea: { height: 120, alignItems: 'flex-start', paddingVertical: 0 },
input: { flex: 1, fontSize: 16 },
prefixContainer: {
flexDirection: 'row',

View File

@@ -76,6 +76,17 @@ const StepThree = forwardRef(({ formData, updateForm, data }: StepProps, ref) =>
}
};
const toggleSelectAllCompanies = () => {
const selected = formData.company || [];
if (selected.length === corporations.length) {
// Deselect all
updateForm('company', []);
} else {
// Select all
updateForm('company', corporations);
}
};
useEffect(() => {
const country = statesData?.find((c) => c.code === formData.country);
setRegions(country?.region || []);
@@ -90,13 +101,19 @@ const StepThree = forwardRef(({ formData, updateForm, data }: StepProps, ref) =>
const country = statesData?.find((c) => c.code === formData.country);
const region = country?.region.find((r) => r.code === formData.region);
setDistricts(region?.districts || []);
if (!region?.districts.some((d) => d.code === formData.district)) {
// If region is 'all', automatically set district to 'all'
if (formData.region === 'all') {
updateForm('district', 'all');
} else if (!region?.districts.some((d) => d.code === formData.district)) {
updateForm('district', '');
}
}, [formData.region, formData.country, statesData]);
const getLabel = (arr: { name: string; code: string }[], val: string) =>
arr.find((item) => item.code === val)?.name || t('— Tanlang —');
const getLabel = (arr: { name: string; code: string }[], val: string) => {
if (val === 'all') return t('Hammasi');
return arr.find((item) => item.code === val)?.name || t('— Tanlang —');
};
const renderCompanyItem = ({ item }: ListRenderItemInfo<{ id: number; latter: string }>) => {
const isSelected = formData.company?.some((c: any) => c.id === item.id);
@@ -157,7 +174,13 @@ const StepThree = forwardRef(({ formData, updateForm, data }: StepProps, ref) =>
<TouchableOpacity
style={[
styles.pickerButton,
{ backgroundColor: theme.cardBg, borderColor: theme.cardBorder },
{
backgroundColor: theme.cardBg,
borderColor: theme.cardBorder,
flexDirection: 'row',
alignItems: 'center',
gap: 10,
},
]}
onPress={() => setShowCountry(true)}
>
@@ -190,9 +213,18 @@ const StepThree = forwardRef(({ formData, updateForm, data }: StepProps, ref) =>
<TouchableOpacity
style={[
styles.pickerButton,
{ backgroundColor: theme.cardBg, borderColor: theme.cardBorder },
{
backgroundColor: theme.cardBg,
borderColor: theme.cardBorder,
opacity: formData.region === 'all' ? 0.5 : 1,
},
]}
onPress={() => setShowDistrict(true)}
onPress={() => {
if (formData.region !== 'all') {
setShowDistrict(true);
}
}}
disabled={formData.region === 'all'}
>
<Text style={[styles.pickerText, { color: theme.text }]}>
{getLabel(
@@ -202,9 +234,34 @@ const StepThree = forwardRef(({ formData, updateForm, data }: StepProps, ref) =>
</Text>
</TouchableOpacity>
<Text style={[styles.sectionTitle, { color: theme.text }]}>
{t('Reklama joylashtirish kompaniyasi')}
</Text>
<View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
<Text style={[styles.sectionTitle, { color: theme.text }]}>
{t('Reklama joylashtirish kompaniyasi')}
</Text>
<TouchableOpacity
style={[
styles.selectAllButton,
{
backgroundColor:
formData.company?.length === corporations.length ? theme.primary : theme.cardBg,
borderColor: theme.primary,
},
]}
onPress={toggleSelectAllCompanies}
>
<Text
style={[
styles.selectAllText,
{
color:
formData.company?.length === corporations.length ? '#fff' : theme.primary,
},
]}
>
{formData.company?.length === corporations.length ? t('Bekor qilish') : t('Hammasi')}
</Text>
</TouchableOpacity>
</View>
<FlatList
data={corporations}
renderItem={renderCompanyItem}
@@ -232,21 +289,29 @@ const StepThree = forwardRef(({ formData, updateForm, data }: StepProps, ref) =>
isOpen={showCountry}
onClose={() => setShowCountry(false)}
selectedValue={formData.country}
data={statesData ? statesData.map((c) => ({ label: c.name, value: c.code })) : []}
data={
statesData ? statesData.map((c) => ({ label: c.name, value: c.code, flag: c.flag })) : []
}
onSelect={(v) => updateForm('country', v)}
/>
<CategorySelectorBottomSheet
isOpen={showRegion}
onClose={() => setShowRegion(false)}
selectedValue={formData.region}
data={regions.map((r) => ({ label: r.name, value: r.code }))}
data={[
{ label: t('Hammasi'), value: 'all' },
...regions.map((r) => ({ label: r.name, value: r.code })),
]}
onSelect={(v) => updateForm('region', v)}
/>
<CategorySelectorBottomSheet
isOpen={showDistrict}
onClose={() => setShowDistrict(false)}
selectedValue={formData.district}
data={districts.map((d) => ({ label: d.name, value: d.code }))}
data={[
{ label: t('Hammasi'), value: 'all' },
...districts.map((d) => ({ label: d.name, value: d.code })),
]}
onSelect={(v) => updateForm('district', v)}
/>
</ScrollView>
@@ -286,4 +351,14 @@ const styles = StyleSheet.create({
priceLine: { fontSize: 15 },
totalPrice: { fontSize: 18, fontWeight: '700', marginTop: 6 },
error: { fontWeight: '600', marginBottom: 10 },
selectAllButton: {
paddingHorizontal: 16,
paddingVertical: 8,
borderRadius: 8,
borderWidth: 1,
},
selectAllText: {
fontSize: 14,
fontWeight: '600',
},
});