Skip to content

Commit

Permalink
Feat: [돌봄급구] 돌봄급구 페이지 ui 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
Yellowtoast committed Feb 5, 2024
1 parent 8a7bab6 commit dbe5eb6
Show file tree
Hide file tree
Showing 22 changed files with 392 additions and 171 deletions.
Binary file added assets/imgs/common/icon_cal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/imgs/common/icon_pay.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/imgs/common/icon_pin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/imgs/home/icon_chat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/imgs/home/icon_community.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/imgs/home/icon_home.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/imgs/home/icon_pin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/imgs/home/icon_user.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion lib/core/constants/images.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@ abstract class PNDImages {
static const String chat = _homePath + 'icon_chat.png';
static const String user = _homePath + 'icon_user.png';

static const String locationPin = _homePath + 'icon_pin.png';
static const String _commonPath = _basePath + 'common/';
static const String location = _commonPath + 'icon_pin.png';
static const String payment = _commonPath + 'icon_pay.png';
static const String calander = _commonPath + 'icon_cal.png';
}
2 changes: 2 additions & 0 deletions lib/core/constants/sizes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';

/// Constant sizes to be used in the app (paddings, gaps, rounded corners etc.)
class PNDSizes {
static const p2 = 2.0;
static const p4 = 4.0;
static const p8 = 8.0;
static const p12 = 12.0;
Expand All @@ -14,6 +15,7 @@ class PNDSizes {
}

/// Constant gap widths
const gapW2 = SizedBox(width: PNDSizes.p2);
const gapW4 = SizedBox(width: PNDSizes.p4);
const gapW8 = SizedBox(width: PNDSizes.p8);
const gapW12 = SizedBox(width: PNDSizes.p12);
Expand Down
18 changes: 9 additions & 9 deletions lib/core/constants/text_style.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,20 @@ abstract class AppTextStyle {
fontWeight: FontWeight.w800,
);

static final TextStyle headlineBold1 = pretendardBoldStyle(24, 33);
static final TextStyle headlineBold2 = pretendardBoldStyle(20, 24);
static final TextStyle headlineBold1 = pretendardSemiBoldStyle(22, 29);
static final TextStyle headlineBold2 = pretendardSemiBoldStyle(20, 24);

static final TextStyle headlineRegular1 = pretendardRegularStyle(24, 33);
static final TextStyle headlineRegular2 = pretendardRegularStyle(20, 24);

static final TextStyle headlineMedium1 = pretendardMediumStyle(24, 33);
static final TextStyle headlineMedium1 = pretendardMediumStyle(22, 29);
static final TextStyle headlineMedium2 = pretendardMediumStyle(20, 24);

static final TextStyle headlineRegular1 = pretendardRegularStyle(22, 29);
static final TextStyle headlineRegular2 = pretendardRegularStyle(20, 24);

static final TextStyle bodyBold1 = pretendardSemiBoldStyle(16, 19);
static final TextStyle bodyBold2 = pretendardRegularStyle(14, 17);
static final TextStyle bodyBold3 = pretendardRegularStyle(12, 14);
static final TextStyle bodyBold2 = pretendardSemiBoldStyle(14, 17);
static final TextStyle bodyBold3 = pretendardSemiBoldStyle(12, 14);

static final TextStyle bodyRegular1 = pretendardSemiBoldStyle(16, 19);
static final TextStyle bodyRegular1 = pretendardRegularStyle(16, 19);
static final TextStyle bodyRegular2 = pretendardRegularStyle(14, 17);
static final TextStyle bodyRegular3 = pretendardRegularStyle(12, 14);
}
1 change: 1 addition & 0 deletions lib/presentation/pages/home/home_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:pets_next_door_flutter/core/constants/colors.dart';
import 'package:pets_next_door_flutter/core/constants/images.dart';
import 'package:pets_next_door_flutter/core/constants/sizes.dart';
import 'package:pets_next_door_flutter/core/constants/text_style.dart';
import 'package:pets_next_door_flutter/presentation/pages/home/home_event.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ class _HomeLocationButton extends StatelessWidget {
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(Icons.location_on_sharp),
Image.asset(
PNDImages.location,
width: 24,
height: 24,
),
gapW4,
Row(
children: [
Expand Down
28 changes: 28 additions & 0 deletions lib/presentation/pages/pet_sos/layouts/pet_filter.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
part of '../pet_sos_view.dart';

/// 돌봄급구 펫타입 필터 영역
/// Radio 버튼 형식으로 구현되어 있음
class _PetSosPetFilter extends ConsumerWidget with PetSosEvent {
const _PetSosPetFilter();

@override
Widget build(BuildContext context, WidgetRef ref) {
final selectedPetFilter = ref.watch(petSosFilterProvider).petTypeFilter;

return Wrap(
spacing: 8,
children: [
...PetTypeFilter.values
.map((petType) => GestureDetector(
onTap: () => onPetTypeChanged(ref, petType),
child: PndRadioButtonItem(
groupValue: selectedPetFilter,
value: petType,
text: petType.displayName,
),
))
.toList()
],
);
}
}
47 changes: 47 additions & 0 deletions lib/presentation/pages/pet_sos/layouts/pet_sos_list_view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
part of '../pet_sos_view.dart';

class _PetSosListView extends HookConsumerWidget {
const _PetSosListView({
this.onScrollDirectionChanged,
});

final void Function(ScrollDirection)? onScrollDirectionChanged;

@override
Widget build(BuildContext context, WidgetRef ref) {
useAutomaticKeepAlive();

final _scrollController = useScrollController();

useEffect(() {
void _callBack() {
onScrollDirectionChanged
?.call(_scrollController.position.userScrollDirection);
}

_scrollController.addListener(_callBack);
return () => _scrollController.removeListener(_callBack);
}, [_scrollController]);

return Expanded(
child: ListView.separated(
itemCount: 10,
controller: _scrollController,
shrinkWrap: true,
itemBuilder: (context, index) => PndPostListTile.sosPage(
imageUrl:
'https://img1.daumcdn.net/thumb/R800x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FP6btQ%2Fbtq2dCpzo9w%2F6KwuwdcKiC01N800kBegAk%2Fimg.jpg',
title: '안녕하세요 푸들 한마리 돌봄 급하게 구합니다.',
dateInfo: '23.03.21 ~ 23.03.28',
location: '용답동',
pay: '시급 9000원',
),
separatorBuilder: (context, index) => Divider(
height: 1,
thickness: 1,
color: AppColor.of.gray20,
),
),
);
}
}
24 changes: 24 additions & 0 deletions lib/presentation/pages/pet_sos/layouts/sort_filter.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
part of '../pet_sos_view.dart';

/// 돌봄급구 게시물 정렬 필터 영역
/// 드롭다운 메뉴 형식으로 구현되어 있음
class _PetSosSortFilter extends ConsumerWidget with PetSosEvent {
const _PetSosSortFilter();

@override
Widget build(BuildContext context, WidgetRef ref) {
final selectedSortFilter = ref.watch(petSosFilterProvider).sortFilter;
return PndDropdownButton<SortTypeFilter>(
onSelected: (sort) => onSortChanged(ref, sort),
selectedValueStr: selectedSortFilter.displayName,
itemBuilder: (_) => SortTypeFilter.values
.map(
(sortType) => PndDropdownItem(
value: sortType,
valueStr: sortType.displayName,
),
)
.toList(),
);
}
}
183 changes: 23 additions & 160 deletions lib/presentation/pages/pet_sos/pet_sos_view.dart
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:pets_next_door_flutter/app/router/app_router.dart';
import 'package:pets_next_door_flutter/core/constants/sizes.dart';
import 'package:pets_next_door_flutter/core/constants/text_style.dart';
import 'package:pets_next_door_flutter/core/constants/colors.dart';
import 'package:pets_next_door_flutter/core/enums/pet_type_filter.enum.dart';
import 'package:pets_next_door_flutter/core/enums/sort_type_filter.enum.dart';
import 'package:pets_next_door_flutter/presentation/pages/pet_sos/pet_sos_event.dart';
import 'package:pets_next_door_flutter/presentation/pages/pet_sos/providers/pet_sos_filter_provider.dart';
import 'package:pets_next_door_flutter/presentation/widgets/button/radio_button.dart';
import 'package:pets_next_door_flutter/presentation/widgets/dropdown/dropdown_button.dart';
import 'package:pets_next_door_flutter/presentation/widgets/dropdown/dropdown_item.dart';
import 'package:pets_next_door_flutter/presentation/widgets/list_tile/post_list_tile.dart';

class PetSosView extends HookConsumerWidget {
part 'layouts/pet_filter.dart';
part 'layouts/pet_sos_list_view.dart';
part 'layouts/sort_filter.dart';

class PetSosView extends StatelessWidget {
const PetSosView({
super.key,
this.onScrollDirectionChanged,
Expand All @@ -20,171 +25,29 @@ class PetSosView extends HookConsumerWidget {
final void Function(ScrollDirection)? onScrollDirectionChanged;

@override
Widget build(BuildContext context, WidgetRef ref) {
useAutomaticKeepAlive();

final _scrollController = useScrollController();

useEffect(() {
void _callBack() {
onScrollDirectionChanged
?.call(_scrollController.position.userScrollDirection);
}

_scrollController.addListener(_callBack);
return () => _scrollController.removeListener(_callBack);
}, [_scrollController]);

Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const _SortFilter(),
const _PetFilter(),
],
),
),
Expanded(
child: ListView.separated(
controller: _scrollController,
shrinkWrap: true,
itemBuilder: (context, index) => ContentsListTile(),
separatorBuilder: (context, index) => Divider(),
itemCount: 10),
_buildPetSosFilterGroup(),
_PetSosListView(
onScrollDirectionChanged: onScrollDirectionChanged,
)
],
);
}
}

class ContentsListTile extends StatelessWidget {
const ContentsListTile({
super.key,
});

@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => context.goNamed(AppRoute.signIn.name),
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 88,
width: 88,
color: Colors.yellow,
),
gapW8,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'푸들 한마리 급하게 ㅁㅇ너랴ㅐㅓㅁㅇㄴ래ㅑ머ㅔㅐㅑ',
softWrap: false,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
),
Text(
'23.03.21 ~ 23.03.28',
softWrap: false,
),
Text(
'용답동',
softWrap: false,
),
Text(
'시급 9000원',
softWrap: false,
),
],
),
)
],
),
Padding _buildPetSosFilterGroup() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
_PetSosSortFilter(),
_PetSosPetFilter(),
],
),
);
}
}

class _SortFilter extends ConsumerWidget with PetSosEvent {
const _SortFilter();

@override
Widget build(BuildContext context, WidgetRef ref) {
return PopupMenuButton(
surfaceTintColor: Colors.white,
constraints: const BoxConstraints.tightFor(width: 90),
position: PopupMenuPosition.under,
child: Container(
height: 45,
child: Row(
children: [
Text(ref.watch(petSosFilterProvider).sortFilter.displayName),
Icon(Icons.keyboard_arrow_down_rounded)
],
)),
onSelected: (sort) => onSortChanged(ref, sort),
itemBuilder: (context) => SortTypeFilter.values
.map((e) => PopupMenuItem(
height: 40,
padding: EdgeInsets.all(0),
value: e,
child: Container(
padding: EdgeInsets.only(left: 10),
child: Text(
e.displayName,
)),
))
.toList(),
);
}
}

class _PetFilter extends ConsumerWidget with PetSosEvent {
const _PetFilter();

@override
Widget build(BuildContext context, WidgetRef ref) {
final filter = ref.watch(petSosFilterProvider);
return Wrap(
spacing: 8,
children: [
...PetTypeFilter.values
.map((petType) => GestureDetector(
onTap: () => onPetTypeChanged(ref, petType),
child: Container(
color: Colors.transparent,
height: 30,
child: Row(
children: [
(filter.petTypeFilter == petType)
? Icon(
Icons.check_box_sharp,
size: 20,
)
: Icon(
Icons.check_box_outline_blank_outlined,
size: 20,
),
gapW4,
Text(
petType.displayName,
style: AppTextStyle.bodyRegular3,
),
],
),
),
))
.toList()
],
);
}
}
Loading

0 comments on commit dbe5eb6

Please sign in to comment.