新增公告功能
This commit is contained in:
45
src/App.tsx
45
src/App.tsx
@ -1,9 +1,11 @@
|
||||
import { useState } from 'react';
|
||||
import './App.css';
|
||||
import { Container, CssBaseline, ThemeProvider, createTheme, Box, Tabs, Tab, Paper } from '@mui/material';
|
||||
import { Container, CssBaseline, ThemeProvider, createTheme, Box, Tabs, Tab, Paper, Button, Typography } from '@mui/material';
|
||||
import GitHubIcon from '@mui/icons-material/GitHub';
|
||||
import { RecordForm } from './components/RecordForm';
|
||||
import { StatsChart } from './components/StatsChart';
|
||||
import { HistoryList } from './components/HistoryList';
|
||||
import { UpdateDialog } from './components/UpdateDialog';
|
||||
|
||||
interface TabPanelProps {
|
||||
children?: React.ReactNode;
|
||||
@ -89,6 +91,7 @@ function App() {
|
||||
<ThemeProvider theme={theme}>
|
||||
<CssBaseline />
|
||||
<Box sx={{ minHeight: '100vh', backgroundColor: 'background.default' }}>
|
||||
<UpdateDialog />
|
||||
<Container maxWidth="md" sx={{ py: 4 }}>
|
||||
<Paper sx={{ p: 3 }}>
|
||||
<Box sx={{ borderBottom: 1, borderColor: 'divider', mb: 2 }}>
|
||||
@ -99,6 +102,46 @@ function App() {
|
||||
</Box>
|
||||
|
||||
<TabPanel value={tabValue} index={0}>
|
||||
{/* 添加 GitHub Star 按钮 */}
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
gap: 1,
|
||||
mb: 4
|
||||
}}>
|
||||
<Typography
|
||||
variant="subtitle2"
|
||||
sx={{
|
||||
color: 'text.secondary',
|
||||
fontWeight: 500,
|
||||
fontSize: '0.875rem'
|
||||
}}
|
||||
>
|
||||
祝愿所有给本项目Star的小伙伴牛子长度翻倍!
|
||||
</Typography>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
startIcon={<GitHubIcon />}
|
||||
onClick={() => window.open('https://github.com/zzzdajb/DickHelper', '_blank')}
|
||||
sx={{
|
||||
borderRadius: 2,
|
||||
textTransform: 'none',
|
||||
fontWeight: 600,
|
||||
background: 'linear-gradient(45deg, #24292e 30%, #40464e 90%)',
|
||||
'&:hover': {
|
||||
background: 'linear-gradient(45deg, #40464e 30%, #586069 90%)',
|
||||
transform: 'translateY(-2px)',
|
||||
boxShadow: '0 4px 12px rgba(0,0,0,0.15)'
|
||||
},
|
||||
transition: 'all 0.3s ease'
|
||||
}}
|
||||
>
|
||||
⭐ Star on GitHub
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
||||
<Box>
|
||||
<RecordForm />
|
||||
|
@ -186,7 +186,7 @@ export const RecordForm = () => {
|
||||
WebkitBackgroundClip: 'text',
|
||||
WebkitTextFillColor: 'transparent'
|
||||
}}>
|
||||
记录新的自慰
|
||||
记录新的手艺活
|
||||
</Typography>
|
||||
|
||||
<Box sx={{
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Box, Typography, Grid, Paper, Button } from '@mui/material';
|
||||
import { Box, Typography, Grid, Paper } from '@mui/material'; // 删除 Button 导入
|
||||
import { StorageService } from '../services/storage';
|
||||
import { MasturbationRecord, MasturbationStats } from '../types/record';
|
||||
import GitHubIcon from '@mui/icons-material/GitHub';
|
||||
// 删除 GitHubIcon 导入
|
||||
|
||||
const DAYS_IN_WEEK = 7;
|
||||
const WEEKS_TO_SHOW = 4; // 将显示时间范围改为4周
|
||||
const WEEKDAYS = ['一', '二', '三', '四', '五', '六', '日'];
|
||||
const GITHUB_REPO_URL = 'https://github.com/zzzdajb/DickHelper'; // 替换为实际的Github仓库地址
|
||||
// 删除 GITHUB_REPO_URL 常量
|
||||
|
||||
/**
|
||||
* 统计图表组件
|
||||
@ -165,44 +165,7 @@ export const StatsChart = () => {
|
||||
统计数据
|
||||
</Typography>
|
||||
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
gap: 1,
|
||||
mb: 4
|
||||
}}>
|
||||
<Typography
|
||||
variant="subtitle2"
|
||||
sx={{
|
||||
color: 'text.secondary',
|
||||
fontWeight: 500,
|
||||
fontSize: '0.875rem'
|
||||
}}
|
||||
>
|
||||
求求你给个Star!
|
||||
</Typography>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
startIcon={<GitHubIcon />}
|
||||
onClick={() => window.open(GITHUB_REPO_URL, '_blank')}
|
||||
sx={{
|
||||
borderRadius: 2,
|
||||
textTransform: 'none',
|
||||
fontWeight: 600,
|
||||
background: 'linear-gradient(45deg, #24292e 30%, #40464e 90%)',
|
||||
'&:hover': {
|
||||
background: 'linear-gradient(45deg, #40464e 30%, #586069 90%)',
|
||||
transform: 'translateY(-2px)',
|
||||
boxShadow: '0 4px 12px rgba(0,0,0,0.15)'
|
||||
},
|
||||
transition: 'all 0.3s ease'
|
||||
}}
|
||||
>
|
||||
⭐ Star on GitHub
|
||||
</Button>
|
||||
</Box>
|
||||
{/* 删除整个 GitHub Star 按钮的 Box 组件 */}
|
||||
|
||||
<Grid container spacing={2} sx={{ mb: 3 }} columns={12}>
|
||||
<Grid item xs={12} sm={6}>
|
||||
@ -371,7 +334,7 @@ export const StatsChart = () => {
|
||||
color: 'text.primary'
|
||||
}}
|
||||
>
|
||||
自慰日历
|
||||
发射日历
|
||||
</Typography>
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
|
155
src/components/UpdateDialog.tsx
Normal file
155
src/components/UpdateDialog.tsx
Normal file
@ -0,0 +1,155 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Dialog, DialogTitle, DialogContent, DialogActions, Button, Typography, Box } from '@mui/material';
|
||||
|
||||
interface UpdateInfo {
|
||||
version: string;
|
||||
date: string;
|
||||
changes: string[];
|
||||
}
|
||||
|
||||
const VERSION_HISTORY: UpdateInfo[] = [
|
||||
{
|
||||
version: 'v0.1.1',
|
||||
date: '2025-02-20',
|
||||
changes: [
|
||||
'非常感谢每一个给我Star的小伙伴!',
|
||||
'新增更新公告弹窗,方便用户了解最新变化',
|
||||
'调整了一些文字内容,防止尴尬',
|
||||
'修复了一些已知问题'
|
||||
]
|
||||
},
|
||||
{
|
||||
version: 'v0.1.0',
|
||||
date: '2025-02-20',
|
||||
changes: [
|
||||
'正式发布',
|
||||
'基础记录功能',
|
||||
'统计图表功能',
|
||||
'历史记录管理'
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
const LOCAL_STORAGE_KEY = 'next_update_notice_date';
|
||||
|
||||
export const UpdateDialog = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const nextNoticeDate = localStorage.getItem(LOCAL_STORAGE_KEY);
|
||||
const now = new Date();
|
||||
|
||||
if (!nextNoticeDate || new Date(nextNoticeDate) <= now) {
|
||||
setOpen(true);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleClose = (dontShowFor3Days: boolean = false) => {
|
||||
setOpen(false);
|
||||
// 只有当用户选择"3天内不再提示
|
||||
if (dontShowFor3Days) {
|
||||
const nextDate = new Date();
|
||||
nextDate.setDate(nextDate.getDate() + 3);
|
||||
localStorage.setItem(LOCAL_STORAGE_KEY, nextDate.toISOString());
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
aria-labelledby="update-dialog-title"
|
||||
maxWidth="sm"
|
||||
fullWidth
|
||||
>
|
||||
<DialogTitle id="update-dialog-title" sx={{
|
||||
background: 'linear-gradient(45deg, #2196f3 30%, #64b5f6 90%)',
|
||||
color: 'white',
|
||||
fontWeight: 700
|
||||
}}>
|
||||
更新公告
|
||||
</DialogTitle>
|
||||
<DialogContent sx={{ mt: 2, maxHeight: 400, overflowY: 'auto' }}>
|
||||
{VERSION_HISTORY.map((version, versionIndex) => (
|
||||
<Box key={version.version} sx={{ mb: versionIndex < VERSION_HISTORY.length - 1 ? 4 : 2 }}>
|
||||
<Typography variant="h6" sx={{
|
||||
fontWeight: 600,
|
||||
color: versionIndex === 0 ? 'primary.main' : 'text.primary',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 1
|
||||
}}>
|
||||
{version.version}
|
||||
{versionIndex === 0 && (
|
||||
<Typography
|
||||
component="span"
|
||||
variant="caption"
|
||||
sx={{
|
||||
backgroundColor: 'primary.main',
|
||||
color: 'white',
|
||||
px: 1,
|
||||
py: 0.5,
|
||||
borderRadius: 1,
|
||||
fontSize: '0.75rem'
|
||||
}}
|
||||
>
|
||||
最新
|
||||
</Typography>
|
||||
)}
|
||||
</Typography>
|
||||
<Typography variant="subtitle2" color="text.secondary" sx={{ mb: 2 }}>
|
||||
发布日期:{version.date}
|
||||
</Typography>
|
||||
<Typography variant="subtitle1" sx={{ fontWeight: 500, mb: 1 }}>
|
||||
更新内容:
|
||||
</Typography>
|
||||
<Box component="ul" sx={{ mt: 0, pl: 2 }}>
|
||||
{version.changes.map((change, index) => (
|
||||
<Typography
|
||||
key={index}
|
||||
component="li"
|
||||
variant="body1"
|
||||
sx={{ mb: 1, color: 'text.secondary' }}
|
||||
>
|
||||
{change}
|
||||
</Typography>
|
||||
))}
|
||||
</Box>
|
||||
</Box>
|
||||
))}
|
||||
</DialogContent>
|
||||
<DialogActions sx={{ p: 2, pt: 0, gap: 1 }}>
|
||||
<Button
|
||||
onClick={() => handleClose(true)}
|
||||
variant="outlined"
|
||||
sx={{
|
||||
borderRadius: 2,
|
||||
borderColor: 'primary.main',
|
||||
color: 'primary.main',
|
||||
'&:hover': {
|
||||
borderColor: 'primary.dark',
|
||||
backgroundColor: 'rgba(33, 150, 243, 0.08)'
|
||||
}
|
||||
}}
|
||||
>
|
||||
3天内不再提示
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => handleClose()}
|
||||
variant="contained"
|
||||
sx={{
|
||||
borderRadius: 2,
|
||||
px: 3,
|
||||
background: 'linear-gradient(45deg, #2196f3 30%, #64b5f6 90%)',
|
||||
'&:hover': {
|
||||
background: 'linear-gradient(45deg, #1976d2 30%, #2196f3 90%)'
|
||||
}
|
||||
}}
|
||||
>
|
||||
我知道了
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
Reference in New Issue
Block a user