refactor(ui): 删除不再使用的UI组件
清理代码库中不再使用的UI组件,包括FrostedGlass、SearchBar、CourseCard、GradientHeader、LiveStreamCard、SummerCampCard和ActivityCard。这些组件在当前项目中已无作用,删除以保持代码简洁。
Showing
7 changed files
with
0 additions
and
352 deletions
src/components/ui/ActivityCard.jsx
deleted
100644 → 0
| 1 | -import React from 'react'; | ||
| 2 | -import { Link } from 'react-router-dom'; | ||
| 3 | -import FrostedGlass from './FrostedGlass'; | ||
| 4 | - | ||
| 5 | -/** | ||
| 6 | - * ActivityCard component displays an activity item in the activities list | ||
| 7 | - * | ||
| 8 | - * @param {Object} props - Component props | ||
| 9 | - * @param {Object} props.activity - Activity data | ||
| 10 | - * @returns {JSX.Element} ActivityCard component | ||
| 11 | - */ | ||
| 12 | -const ActivityCard = ({ activity }) => { | ||
| 13 | - // Function to get the appropriate status class | ||
| 14 | - const getStatusClass = (status) => { | ||
| 15 | - switch (status) { | ||
| 16 | - case '活动中': | ||
| 17 | - return 'bg-blue-100 text-blue-600'; | ||
| 18 | - case '进行中': | ||
| 19 | - return 'bg-green-100 text-green-600'; | ||
| 20 | - case '即将开始': | ||
| 21 | - return 'bg-orange-100 text-orange-600'; | ||
| 22 | - case '已结束': | ||
| 23 | - return 'bg-gray-100 text-gray-600'; | ||
| 24 | - default: | ||
| 25 | - return 'bg-gray-100 text-gray-600'; | ||
| 26 | - } | ||
| 27 | - }; | ||
| 28 | - | ||
| 29 | - return ( | ||
| 30 | - <Link to={`/activities/${activity.id}`}> | ||
| 31 | - <FrostedGlass className="flex overflow-hidden rounded-xl shadow-sm"> | ||
| 32 | - {/* Activity Image */} | ||
| 33 | - <div className="w-1/3 h-28 relative"> | ||
| 34 | - <img | ||
| 35 | - src={activity.imageUrl} | ||
| 36 | - alt={activity.title} | ||
| 37 | - className="w-full h-full object-cover" | ||
| 38 | - /> | ||
| 39 | - {activity.isHot && ( | ||
| 40 | - <div className="absolute top-0 left-0 bg-red-500 text-white text-xs px-2 py-0.5"> | ||
| 41 | - 热门 | ||
| 42 | - </div> | ||
| 43 | - )} | ||
| 44 | - </div> | ||
| 45 | - | ||
| 46 | - {/* Activity Info */} | ||
| 47 | - <div className="flex-1 p-3 flex flex-col justify-between"> | ||
| 48 | - <div> | ||
| 49 | - <h3 className="font-medium text-base mb-1 line-clamp-1">{activity.title}</h3> | ||
| 50 | - | ||
| 51 | - {/* Status Tags */} | ||
| 52 | - <div className="flex items-center space-x-2 mb-1"> | ||
| 53 | - <span className={`px-2 py-0.5 rounded-full text-xs ${getStatusClass(activity.status)}`}> | ||
| 54 | - {activity.status} | ||
| 55 | - </span> | ||
| 56 | - {activity.isFree && ( | ||
| 57 | - <span className="px-2 py-0.5 rounded-full text-xs bg-green-100 text-green-600"> | ||
| 58 | - 免费 | ||
| 59 | - </span> | ||
| 60 | - )} | ||
| 61 | - </div> | ||
| 62 | - </div> | ||
| 63 | - | ||
| 64 | - {/* Location and Time */} | ||
| 65 | - <div className="text-xs text-gray-500 space-y-1"> | ||
| 66 | - <div className="flex items-center"> | ||
| 67 | - <svg xmlns="http://www.w3.org/2000/svg" className="h-3.5 w-3.5 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | ||
| 68 | - <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" /> | ||
| 69 | - <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" /> | ||
| 70 | - </svg> | ||
| 71 | - <span>{activity.location}</span> | ||
| 72 | - </div> | ||
| 73 | - | ||
| 74 | - <div className="flex items-center"> | ||
| 75 | - <svg xmlns="http://www.w3.org/2000/svg" className="h-3.5 w-3.5 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | ||
| 76 | - <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /> | ||
| 77 | - </svg> | ||
| 78 | - <span>{activity.period}</span> | ||
| 79 | - </div> | ||
| 80 | - </div> | ||
| 81 | - | ||
| 82 | - {/* Bottom Info Section */} | ||
| 83 | - <div className="mt-1 flex items-center justify-between"> | ||
| 84 | - {activity.price ? ( | ||
| 85 | - <div className="flex items-baseline"> | ||
| 86 | - <span className="text-red-500 font-medium">¥{activity.price}</span> | ||
| 87 | - {activity.originalPrice && ( | ||
| 88 | - <span className="text-xs text-gray-400 ml-1 line-through">¥{activity.originalPrice}</span> | ||
| 89 | - )} | ||
| 90 | - </div> | ||
| 91 | - ) : ( | ||
| 92 | - <div></div> // Empty div for spacing when no price | ||
| 93 | - )} | ||
| 94 | - | ||
| 95 | - <div className="flex items-center text-xs text-gray-500"> | ||
| 96 | - <svg xmlns="http://www.w3.org/2000/svg" className="h-3.5 w-3.5 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | ||
| 97 | - <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" /> | ||
| 98 | - </svg> | ||
| 99 | - <span>{activity.participantsCount || '15'}/{activity.maxParticipants || '30'}</span> | ||
| 100 | - </div> | ||
| 101 | - </div> | ||
| 102 | - </div> | ||
| 103 | - </FrostedGlass> | ||
| 104 | - </Link> | ||
| 105 | - ); | ||
| 106 | -}; | ||
| 107 | - | ||
| 108 | -export default ActivityCard; | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/components/ui/CourseCard.jsx
deleted
100644 → 0
| 1 | -import React from 'react'; | ||
| 2 | -import { Link } from 'react-router-dom'; | ||
| 3 | - | ||
| 4 | -/** | ||
| 5 | - * CourseCard component displays a course item in the course list | ||
| 6 | - * | ||
| 7 | - * @param {Object} props - Component props | ||
| 8 | - * @param {Object} props.course - Course data | ||
| 9 | - * @returns {JSX.Element} CourseCard component | ||
| 10 | - */ | ||
| 11 | -const CourseCard = ({ course }) => { | ||
| 12 | - return ( | ||
| 13 | - <Link to={`/courses/${course.id}`} className="flex bg-white rounded-lg overflow-hidden shadow-sm"> | ||
| 14 | - <div className="w-1/3 h-28"> | ||
| 15 | - <img | ||
| 16 | - src={course.imageUrl} | ||
| 17 | - alt={course.title} | ||
| 18 | - className="w-full h-full object-cover" | ||
| 19 | - /> | ||
| 20 | - </div> | ||
| 21 | - <div className="flex-1 p-3 flex flex-col justify-between"> | ||
| 22 | - <div> | ||
| 23 | - <h3 className="font-medium text-sm mb-1 line-clamp-2">{course.title}</h3> | ||
| 24 | - <div className="text-gray-500 text-xs">{course.subtitle}</div> | ||
| 25 | - </div> | ||
| 26 | - <div className="flex justify-between items-end mt-1"> | ||
| 27 | - <div className="text-orange-500 font-semibold">¥{course.price}</div> | ||
| 28 | - <div className="text-gray-400 text-xs"> | ||
| 29 | - {course.subscribers}人订阅 | ||
| 30 | - </div> | ||
| 31 | - </div> | ||
| 32 | - <div className="text-gray-400 text-xs"> | ||
| 33 | - 已更新{course.updatedLessons}期 | {course.subscribers}人订阅 | ||
| 34 | - </div> | ||
| 35 | - </div> | ||
| 36 | - </Link> | ||
| 37 | - ); | ||
| 38 | -}; | ||
| 39 | - | ||
| 40 | -export default CourseCard; | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/components/ui/FrostedGlass.jsx
deleted
100644 → 0
| 1 | -import React from 'react'; | ||
| 2 | - | ||
| 3 | -/** | ||
| 4 | - * FrostedGlass component creates a container with a frosted glass effect | ||
| 5 | - * using backdrop-filter blur and a semi-transparent white background. | ||
| 6 | - * | ||
| 7 | - * @param {Object} props - Component props | ||
| 8 | - * @param {ReactNode} props.children - Child elements | ||
| 9 | - * @param {string} props.className - Additional CSS classes | ||
| 10 | - * @returns {JSX.Element} FrostedGlass component | ||
| 11 | - */ | ||
| 12 | -const FrostedGlass = ({ children, className = '' }) => { | ||
| 13 | - return ( | ||
| 14 | - <div | ||
| 15 | - className={`bg-white/20 backdrop-blur-md rounded-xl border border-white/30 | ||
| 16 | - shadow-lg ${className}`} | ||
| 17 | - > | ||
| 18 | - {children} | ||
| 19 | - </div> | ||
| 20 | - ); | ||
| 21 | -}; | ||
| 22 | - | ||
| 23 | -export default FrostedGlass; | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/components/ui/GradientHeader.jsx
deleted
100644 → 0
| 1 | -import React from 'react'; | ||
| 2 | - | ||
| 3 | -/** | ||
| 4 | - * GradientHeader component for page headers with gradient background | ||
| 5 | - * and navigation elements. | ||
| 6 | - * | ||
| 7 | - * @param {Object} props - Component props | ||
| 8 | - * @param {string} props.title - Header title | ||
| 9 | - * @param {boolean} props.showBackButton - Whether to show back button | ||
| 10 | - * @param {Function} props.onBack - Back button click handler | ||
| 11 | - * @param {ReactNode} props.rightContent - Content to display on the right side | ||
| 12 | - * @returns {JSX.Element} GradientHeader component | ||
| 13 | - */ | ||
| 14 | -const GradientHeader = ({ title, showBackButton = false, onBack, rightContent }) => { | ||
| 15 | - return ( | ||
| 16 | - <header className="bg-gradient-to-r from-green-50 to-blue-50 p-4 relative"> | ||
| 17 | - <div className="flex items-center justify-between"> | ||
| 18 | - {showBackButton && ( | ||
| 19 | - <button | ||
| 20 | - onClick={onBack} | ||
| 21 | - className="p-2 rounded-full bg-white/30 backdrop-blur-sm" | ||
| 22 | - aria-label="返回" | ||
| 23 | - > | ||
| 24 | - <svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 text-gray-700" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | ||
| 25 | - <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" /> | ||
| 26 | - </svg> | ||
| 27 | - </button> | ||
| 28 | - )} | ||
| 29 | - <h1 className={`text-xl font-medium text-center ${showBackButton ? 'flex-1' : ''}`}> | ||
| 30 | - {title} | ||
| 31 | - </h1> | ||
| 32 | - {rightContent && <div>{rightContent}</div>} | ||
| 33 | - </div> | ||
| 34 | - </header> | ||
| 35 | - ); | ||
| 36 | -}; | ||
| 37 | - | ||
| 38 | -export default GradientHeader; | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/components/ui/LiveStreamCard.jsx
deleted
100644 → 0
| 1 | -import React from 'react'; | ||
| 2 | -import { Link } from 'react-router-dom'; | ||
| 3 | - | ||
| 4 | -/** | ||
| 5 | - * LiveStreamCard component displays a live stream in the courses page | ||
| 6 | - * | ||
| 7 | - * @param {Object} props - Component props | ||
| 8 | - * @param {Object} props.stream - Stream data | ||
| 9 | - * @returns {JSX.Element} LiveStreamCard component | ||
| 10 | - */ | ||
| 11 | -const LiveStreamCard = ({ stream }) => { | ||
| 12 | - return ( | ||
| 13 | - <div className="relative"> | ||
| 14 | - {/* Live indicator */} | ||
| 15 | - <div className="absolute top-2 left-2 bg-red-500/90 text-white text-xs px-2 py-1 rounded flex items-center z-10"> | ||
| 16 | - <div className="w-2 h-2 bg-white rounded-full mr-1 animate-pulse"></div> | ||
| 17 | - 直播中 | ||
| 18 | - </div> | ||
| 19 | - | ||
| 20 | - <Link to={`/courses/${stream.id}`} className="block rounded-lg overflow-hidden shadow-sm relative"> | ||
| 21 | - <img | ||
| 22 | - src={stream.imageUrl} | ||
| 23 | - alt={stream.title} | ||
| 24 | - className="w-full h-28 object-cover" | ||
| 25 | - /> | ||
| 26 | - | ||
| 27 | - {/* Gradient overlay */} | ||
| 28 | - <div className="absolute inset-0 bg-gradient-to-b from-transparent to-black/60"></div> | ||
| 29 | - | ||
| 30 | - {/* Stream info */} | ||
| 31 | - <div className="absolute bottom-2 left-2 right-2"> | ||
| 32 | - <h3 className="text-white text-sm font-medium">「{stream.title}」{stream.subtitle}</h3> | ||
| 33 | - <div className="flex items-center mt-1"> | ||
| 34 | - <div className="flex -space-x-2"> | ||
| 35 | - <div className="w-5 h-5 rounded-full bg-gray-300 border border-white"></div> | ||
| 36 | - <div className="w-5 h-5 rounded-full bg-gray-400 border border-white"></div> | ||
| 37 | - <div className="w-5 h-5 rounded-full bg-gray-500 border border-white"></div> | ||
| 38 | - </div> | ||
| 39 | - <span className="text-white text-xs ml-1">{stream.viewers}人在看</span> | ||
| 40 | - <button className="ml-auto bg-green-500 text-white text-xs px-2 py-1 rounded"> | ||
| 41 | - 立即观看 | ||
| 42 | - </button> | ||
| 43 | - </div> | ||
| 44 | - </div> | ||
| 45 | - </Link> | ||
| 46 | - </div> | ||
| 47 | - ); | ||
| 48 | -}; | ||
| 49 | - | ||
| 50 | -export default LiveStreamCard; | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/components/ui/SearchBar.jsx
deleted
100644 → 0
| 1 | -import React from 'react'; | ||
| 2 | -import FrostedGlass from './FrostedGlass'; | ||
| 3 | - | ||
| 4 | -/** | ||
| 5 | - * SearchBar component with frosted glass effect | ||
| 6 | - * | ||
| 7 | - * @param {Object} props - Component props | ||
| 8 | - * @param {string} props.placeholder - Placeholder text | ||
| 9 | - * @param {Function} props.onSearch - Search callback function | ||
| 10 | - * @returns {JSX.Element} SearchBar component | ||
| 11 | - */ | ||
| 12 | -const SearchBar = ({ placeholder = '搜索', onSearch }) => { | ||
| 13 | - return ( | ||
| 14 | - <FrostedGlass className="px-4 py-2 mx-4 my-3 flex items-center"> | ||
| 15 | - <svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 text-gray-400 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | ||
| 16 | - <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" /> | ||
| 17 | - </svg> | ||
| 18 | - <input | ||
| 19 | - type="text" | ||
| 20 | - placeholder={placeholder} | ||
| 21 | - className="bg-transparent outline-none flex-1 text-gray-700 placeholder-gray-400" | ||
| 22 | - onChange={(e) => onSearch && onSearch(e.target.value)} | ||
| 23 | - /> | ||
| 24 | - </FrostedGlass> | ||
| 25 | - ); | ||
| 26 | -}; | ||
| 27 | - | ||
| 28 | -export default SearchBar; | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/components/ui/SummerCampCard.jsx
deleted
100644 → 0
| 1 | -import React from 'react'; | ||
| 2 | -import PropTypes from 'prop-types'; | ||
| 3 | - | ||
| 4 | -/** | ||
| 5 | - * SummerCampCard component - displays summer camp information with image background | ||
| 6 | - * @param {Object} props - Component props | ||
| 7 | - * @returns {JSX.Element} - Rendered component | ||
| 8 | - */ | ||
| 9 | -const SummerCampCard = ({ | ||
| 10 | - title = "大国少年-世界正东方", | ||
| 11 | - subtitle = "亲子夏令营", | ||
| 12 | - badge = "亲子夏令营", | ||
| 13 | - price = "¥1280", | ||
| 14 | - discount = "限时优惠", | ||
| 15 | - episodes = 16, | ||
| 16 | - subscribers = 1140 | ||
| 17 | -}) => { | ||
| 18 | - return ( | ||
| 19 | - <div className="relative overflow-hidden rounded-b-3xl shadow-lg"> | ||
| 20 | - {/* Background image with overlay */} | ||
| 21 | - <div | ||
| 22 | - className="absolute inset-0 z-0 bg-cover bg-center" | ||
| 23 | - style={{ | ||
| 24 | - backgroundImage: `url('/assets/images/summer-camp.jpg')`, | ||
| 25 | - filter: 'brightness(0.4)' | ||
| 26 | - }} | ||
| 27 | - ></div> | ||
| 28 | - | ||
| 29 | - {/* Gradient overlay */} | ||
| 30 | - <div className="absolute inset-0 z-1 bg-gradient-to-b from-red-500/70 to-red-600/90"></div> | ||
| 31 | - | ||
| 32 | - {/* Content */} | ||
| 33 | - <div className="relative z-10 p-4"> | ||
| 34 | - <div className="bg-white/10 backdrop-blur-sm rounded-lg p-3 mb-3 inline-block"> | ||
| 35 | - <div className="text-white font-semibold">{badge}</div> | ||
| 36 | - </div> | ||
| 37 | - | ||
| 38 | - <h1 className="text-2xl text-white font-bold mb-1">{title}</h1> | ||
| 39 | - <h2 className="text-lg text-white/90">{subtitle}</h2> | ||
| 40 | - | ||
| 41 | - <div className="mt-4 flex justify-between items-center"> | ||
| 42 | - <div className="text-orange-300 font-bold text-2xl">{price}</div> | ||
| 43 | - <div className="bg-orange-500/30 text-orange-100 text-xs px-3 py-1 rounded-full">{discount}</div> | ||
| 44 | - </div> | ||
| 45 | - | ||
| 46 | - <div className="flex justify-between text-xs text-white/80 mt-3"> | ||
| 47 | - <div>已更新{episodes}期</div> | ||
| 48 | - <div>{subscribers}人订阅</div> | ||
| 49 | - </div> | ||
| 50 | - </div> | ||
| 51 | - </div> | ||
| 52 | - ); | ||
| 53 | -}; | ||
| 54 | - | ||
| 55 | -SummerCampCard.propTypes = { | ||
| 56 | - title: PropTypes.string, | ||
| 57 | - subtitle: PropTypes.string, | ||
| 58 | - badge: PropTypes.string, | ||
| 59 | - price: PropTypes.string, | ||
| 60 | - discount: PropTypes.string, | ||
| 61 | - episodes: PropTypes.number, | ||
| 62 | - subscribers: PropTypes.number | ||
| 63 | -}; | ||
| 64 | - | ||
| 65 | -export default SummerCampCard; | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or login to post a comment