feat: rebuild pet app and backend around core care flows
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
const { secure, toast } = require("../../utils/api");
|
||||
Page({
|
||||
data: { meetups: [], pets: [], selected: [], active: null, userId: "" },
|
||||
onShow() {
|
||||
this.load();
|
||||
},
|
||||
async load() {
|
||||
try {
|
||||
const [meetups, pets, me] = await Promise.all([
|
||||
secure("/meetups"),
|
||||
secure("/pets"),
|
||||
secure("/me"),
|
||||
]);
|
||||
this.setData({
|
||||
meetups: meetups.map((m) => ({
|
||||
...m,
|
||||
date: new Date(m.starts_at).toLocaleString("zh-CN"),
|
||||
})),
|
||||
pets,
|
||||
userId: me.id,
|
||||
});
|
||||
} catch (e) {
|
||||
toast(e);
|
||||
}
|
||||
},
|
||||
create() {
|
||||
wx.navigateTo({ url: "/pages/meetup-edit/meetup-edit" });
|
||||
},
|
||||
open(e) {
|
||||
this.setData({
|
||||
active: this.data.meetups[e.currentTarget.dataset.index],
|
||||
selected: [],
|
||||
});
|
||||
},
|
||||
close() {
|
||||
this.setData({ active: null });
|
||||
},
|
||||
pick(e) {
|
||||
this.setData({ selected: e.detail.selected });
|
||||
},
|
||||
async join() {
|
||||
if (!this.data.selected.length) {
|
||||
wx.showToast({ title: "请选择同行的狗狗", icon: "none" });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await secure("/meetups/" + this.data.active.id + "/join", "POST", {
|
||||
pet_ids: this.data.selected,
|
||||
});
|
||||
wx.showToast({ title: "报名成功", icon: "success" });
|
||||
this.close();
|
||||
this.load();
|
||||
} catch (e) {
|
||||
toast(e);
|
||||
}
|
||||
},
|
||||
async cancel() {
|
||||
const r = await wx.showModal({
|
||||
title: "取消约遛",
|
||||
content: "确定取消这场约遛吗?",
|
||||
});
|
||||
if (!r.confirm) return;
|
||||
try {
|
||||
await secure("/meetups/" + this.data.active.id + "/cancel", "POST");
|
||||
this.close();
|
||||
this.load();
|
||||
} catch (e) {
|
||||
toast(e);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
{ "usingComponents": { "tab-bar": "/components/tab-bar/index", "pet-picker": "/components/pet-picker/index" } }
|
||||
@@ -0,0 +1,62 @@
|
||||
<view class="screen">
|
||||
<view class="eyebrow">LET'S WALK TOGETHER</view>
|
||||
<view class="title">约个伴一起遛 🌿</view>
|
||||
<view class="banner">
|
||||
<text>好天气,和新朋友一起走走</text>
|
||||
<strong>
|
||||
下一次快乐
|
||||
<br />
|
||||
从这里出发
|
||||
</strong>
|
||||
<image src="/assets/corgi-family-five.png" mode="aspectFit" />
|
||||
</view>
|
||||
<view class="row">
|
||||
<text class="section-title">附近的约遛</text>
|
||||
<text class="add" bindtap="create">+ 发起约遛</text>
|
||||
</view>
|
||||
<view
|
||||
wx:for="{{meetups}}"
|
||||
wx:key="id"
|
||||
class="card meetup"
|
||||
data-index="{{index}}"
|
||||
bindtap="open"
|
||||
>
|
||||
<view class="row">
|
||||
<text class="badge">
|
||||
🐾 {{item.participants}} / {{item.max_people}} 人
|
||||
</text>
|
||||
<text class="arrow">›</text>
|
||||
</view>
|
||||
<strong>{{item.title}}</strong>
|
||||
<view class="meta">📍 {{item.place_name}}</view>
|
||||
<view class="meta">🗓 {{item.date}}</view>
|
||||
<view class="desc">{{item.description}}</view>
|
||||
</view>
|
||||
<view wx:if="{{!meetups.length}}" class="empty">
|
||||
还没有约遛,发起第一场吧 🐕
|
||||
</view>
|
||||
<button class="primary" bindtap="create">+ 发起一场约遛</button>
|
||||
</view>
|
||||
<view wx:if="{{active}}" class="overlay">
|
||||
<view class="sheet">
|
||||
<view class="row">
|
||||
<strong>{{active.title}}</strong>
|
||||
<text bindtap="close">×</text>
|
||||
</view>
|
||||
<view class="detail">
|
||||
📍 {{active.place_name}}
|
||||
<br />
|
||||
🗓 {{active.date}}
|
||||
<br />
|
||||
🐕 {{active.participants}} / {{active.max_people}} 人已报名
|
||||
</view>
|
||||
<view class="desc">{{active.description}}</view>
|
||||
<view wx:if="{{active.host_user_id!==userId}}">
|
||||
<view class="select-title">带哪几只?可以多选</view>
|
||||
<pet-picker pets="{{pets}}" selected="{{selected}}" bind:change="pick" />
|
||||
<button class="primary" bindtap="join">带狗狗报名</button>
|
||||
</view>
|
||||
<button wx:else class="secondary" bindtap="cancel">取消这场约遛</button>
|
||||
</view>
|
||||
</view>
|
||||
<tab-bar current="/pages/meetups/meetups" />
|
||||
@@ -0,0 +1,96 @@
|
||||
.banner {
|
||||
background: #dfeee2;
|
||||
border-radius: 34rpx;
|
||||
min-height: 245rpx;
|
||||
padding: 36rpx;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.banner text,
|
||||
.banner strong {
|
||||
display: block;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
.banner text {
|
||||
color: #549375;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
.banner strong {
|
||||
font-size: 35rpx;
|
||||
line-height: 1.3;
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
.banner image {
|
||||
width: 290rpx;
|
||||
height: 220rpx;
|
||||
position: absolute;
|
||||
right: -30rpx;
|
||||
bottom: 0;
|
||||
}
|
||||
.add {
|
||||
font-size: 24rpx;
|
||||
color: #328965;
|
||||
font-weight: 700;
|
||||
}
|
||||
.meetup strong {
|
||||
display: block;
|
||||
font-size: 32rpx;
|
||||
margin: 15rpx 0;
|
||||
}
|
||||
.badge {
|
||||
background: #e8f4ea;
|
||||
color: #429369;
|
||||
border-radius: 99rpx;
|
||||
padding: 8rpx 15rpx;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
.arrow {
|
||||
font-size: 39rpx;
|
||||
color: #a1b2a8;
|
||||
}
|
||||
.meta {
|
||||
font-size: 24rpx;
|
||||
color: #748c7d;
|
||||
margin-top: 9rpx;
|
||||
}
|
||||
.desc {
|
||||
font-size: 24rpx;
|
||||
color: #9aaa9f;
|
||||
margin-top: 15rpx;
|
||||
}
|
||||
.overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: #102a24a0;
|
||||
z-index: 30;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
}
|
||||
.sheet {
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
border-radius: 36rpx 36rpx 0 0;
|
||||
padding: 35rpx 32rpx calc(env(safe-area-inset-bottom) + 35rpx);
|
||||
}
|
||||
.sheet > .row strong {
|
||||
font-size: 34rpx;
|
||||
}
|
||||
.sheet > .row text {
|
||||
font-size: 45rpx;
|
||||
}
|
||||
.detail {
|
||||
font-size: 25rpx;
|
||||
color: #61816e;
|
||||
line-height: 2;
|
||||
margin: 25rpx 0;
|
||||
}
|
||||
.select-title {
|
||||
font-size: 25rpx;
|
||||
font-weight: 700;
|
||||
margin: 30rpx 0 15rpx;
|
||||
}
|
||||
.sheet button {
|
||||
margin-top: 26rpx;
|
||||
width: 100%;
|
||||
}
|
||||
Reference in New Issue
Block a user