Commit 6984d468 authored by caoxu's avatar caoxu

Add: 新增组队页面

parent 228e58b7
......@@ -21,6 +21,11 @@ const router = createRouter({
path: '/city-introduction',
name: 'cityIntroduction',
component: () => import('../views/CityIntroductionView.vue')
},
{
path: '/team-page',
name: 'teamPage',
component: () => import('../views/TeamPageView.vue')
}
]
})
......
<template>
<div class="team-page">
<div class="header">
<button class="back-button" @click="goBack"></button>
<h1 class="page-title">组队页面</h1>
</div>
<div class="main-content">
<div class="team-info-section">
<h2 class="section-title">队伍信息</h2>
<div class="team-info-card">
<div class="team-header">
<div class="team-avatar">
<img src="https://images.unsplash.com/photo-1522075469751-7a4cf3e3b?w=100&h=100&fit=crop" alt="队伍头像" class="avatar-image" />
</div>
<div class="team-details">
<h3 class="team-name">{{ teamInfo.name }}</h3>
<p class="team-description">{{ teamInfo.description }}</p>
<div class="team-meta">
<span class="team-status" :class="teamInfo.status">{{ teamInfo.statusText }}</span>
<span class="team-members">👥 {{ teamInfo.memberCount }}/{{ teamInfo.maxMembers }}</span>
</div>
</div>
</div>
<div class="team-actions">
<button class="action-btn join-btn" @click="joinTeam" v-if="!teamInfo.hasJoined">
+ 加入队伍
</button>
<button class="action-btn leave-btn" @click="leaveTeam" v-else>
退出队伍
</button>
</div>
</div>
</div>
<div class="team-members-section">
<h2 class="section-title">队伍成员</h2>
<div class="members-list">
<div v-for="member in teamMembers" :key="member.id" class="member-card">
<img :src="member.avatar" :alt="member.name" class="member-avatar" />
<div class="member-info">
<h4 class="member-name">{{ member.name }}</h4>
<p class="member-role">{{ member.role }}</p>
<span class="member-status" :class="member.status">{{ member.statusText }}</span>
</div>
<button class="message-btn" @click="sendMessage(member)">
💬
</button>
</div>
</div>
</div>
<div class="create-team-section">
<h2 class="section-title">创建队伍</h2>
<div class="create-team-card">
<div class="form-group">
<label class="form-label">队伍名称</label>
<input type="text" v-model="newTeamName" class="form-input" placeholder="请输入队伍名称" />
</div>
<div class="form-group">
<label class="form-label">队伍描述</label>
<textarea v-model="newTeamDesc" class="form-textarea" placeholder="请输入队伍描述" rows="3"></textarea>
</div>
<div class="form-group">
<label class="form-label">最大人数</label>
<select v-model="newTeamMaxMembers" class="form-select">
<option value="2">2人</option>
<option value="4">4人</option>
<option value="6">6人</option>
<option value="8">8人</option>
<option value="10">10人</option>
</select>
</div>
<button class="create-btn" @click="createTeam">
创建队伍
</button>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const teamInfo = ref({
name: '洛杉矶探索小队',
description: '探索洛杉矶的每一个角落,发现城市的独特魅力!',
status: 'active',
statusText: '招募中',
memberCount: 3,
maxMembers: 6,
hasJoined: false
})
const teamMembers = ref([
{
id: 1,
name: '张三',
avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop',
role: '队长',
status: 'online',
statusText: '在线'
},
{
id: 2,
name: '李四',
avatar: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=100&h=100&fit=crop',
role: '队员',
status: 'online',
statusText: '在线'
},
{
id: 3,
name: '王五',
avatar: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=100&h=100&fit=crop',
role: '队员',
status: 'offline',
statusText: '离线'
},
{
id: 4,
name: '赵六',
avatar: 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=100&h=100&fit=crop',
role: '队员',
status: 'online',
statusText: '在线'
}
])
const newTeamName = ref('')
const newTeamDesc = ref('')
const newTeamMaxMembers = ref(6)
const goBack = () => {
router.back()
}
const joinTeam = () => {
teamInfo.value.hasJoined = true
teamInfo.value.memberCount++
console.log('加入队伍')
}
const leaveTeam = () => {
teamInfo.value.hasJoined = false
teamInfo.value.memberCount--
console.log('退出队伍')
}
const createTeam = () => {
if (!newTeamName.value.trim()) {
alert('请输入队伍名称')
return
}
console.log('创建队伍:', newTeamName.value)
alert('队伍创建成功!')
newTeamName.value = ''
newTeamDesc.value = ''
newTeamMaxMembers.value = 6
}
const sendMessage = (member) => {
console.log('发送消息给:', member.name)
}
</script>
<style scoped>
.team-page {
min-height: 100vh;
background-color: #f5f5f5;
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px;
background-color: white;
position: sticky;
top: 0;
z-index: 10;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.back-button {
background: none;
border: none;
font-size: 24px;
cursor: pointer;
padding: 0;
color: #333;
width: 30px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
}
.page-title {
font-size: 18px;
font-weight: 600;
margin: 0;
color: #333;
flex: 1;
text-align: center;
}
.main-content {
padding: 16px;
}
.team-info-section,
.team-members-section,
.create-team-section {
background-color: white;
border-radius: 12px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
.section-title {
font-size: 20px;
font-weight: 600;
color: #333;
margin: 0 0 16px 0;
padding-bottom: 12px;
border-bottom: 2px solid #42b883;
}
.team-info-card {
display: flex;
flex-direction: column;
gap: 16px;
}
.team-header {
display: flex;
align-items: center;
gap: 16px;
}
.team-avatar {
width: 80px;
height: 80px;
border-radius: 50%;
overflow: hidden;
border: 3px solid #42b883;
}
.avatar-image {
width: 100%;
height: 100%;
object-fit: cover;
}
.team-details {
flex: 1;
}
.team-name {
font-size: 22px;
font-weight: 700;
color: #333;
margin: 0 0 8px 0;
}
.team-description {
font-size: 15px;
color: #666;
margin: 0 0 12px 0;
line-height: 1.6;
}
.team-meta {
display: flex;
gap: 12px;
}
.team-status {
padding: 6px 12px;
border-radius: 12px;
font-size: 14px;
font-weight: 600;
}
.team-status.active {
background-color: #e8f5e9;
color: #4caf50;
}
.team-status.full {
background-color: #fff3e0;
color: #ff9800;
}
.team-members {
font-size: 14px;
color: #666;
display: flex;
align-items: center;
gap: 4px;
}
.team-actions {
display: flex;
gap: 12px;
}
.action-btn {
flex: 1;
padding: 12px 24px;
border: none;
border-radius: 8px;
font-size: 15px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
}
.join-btn {
background-color: #42b883;
color: white;
}
.join-btn:hover {
background-color: #35a37d;
}
.leave-btn {
background-color: #ff6b35;
color: white;
}
.leave-btn:hover {
background-color: #e55a3b;
}
.members-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 12px;
}
.member-card {
display: flex;
align-items: center;
gap: 12px;
padding: 16px;
background-color: #f8f8f8;
border-radius: 8px;
transition: all 0.3s ease;
}
.member-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.member-avatar {
width: 50px;
height: 50px;
border-radius: 50%;
object-fit: cover;
border: 2px solid #42b883;
}
.member-info {
flex: 1;
}
.member-name {
font-size: 16px;
font-weight: 600;
color: #333;
margin: 0 0 4px 0;
}
.member-role {
font-size: 13px;
color: #999;
margin: 0 0 8px 0;
}
.member-status {
display: inline-block;
padding: 4px 8px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
}
.member-status.online {
background-color: #e8f5e9;
color: #4caf50;
}
.member-status.offline {
background-color: #f5f5f5;
color: #9e9e9e;
}
.message-btn {
width: 36px;
height: 36px;
border: 1px solid #e0e0e0;
background-color: white;
border-radius: 50%;
font-size: 16px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
}
.message-btn:hover {
background-color: #42b883;
border-color: #42b883;
}
.create-team-card {
display: flex;
flex-direction: column;
gap: 16px;
}
.form-group {
display: flex;
flex-direction: column;
gap: 8px;
}
.form-label {
font-size: 14px;
font-weight: 600;
color: #333;
margin: 0;
}
.form-input,
.form-textarea,
.form-select {
padding: 12px;
border: 1px solid #e0e0e0;
border-radius: 8px;
font-size: 15px;
color: #333;
transition: all 0.3s ease;
}
.form-input:focus,
.form-textarea:focus,
.form-select:focus {
outline: none;
border-color: #42b883;
box-shadow: 0 0 0 3px rgba(66, 184, 131, 0.1);
}
.form-textarea {
resize: vertical;
min-height: 80px;
}
.create-btn {
padding: 14px 28px;
background-color: #42b883;
color: white;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
margin-top: 8px;
}
.create-btn:hover {
background-color: #35a37d;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(66, 184, 131, 0.2);
}
</style>
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