修正手機介面

This commit is contained in:
2025-09-29 21:00:48 +08:00
parent e5e24d1108
commit 2eb24c6c47
2 changed files with 89 additions and 89 deletions

View File

@@ -249,54 +249,54 @@ function AnalyticsContent() {
<div className="container mx-auto px-4 py-8"> <div className="container mx-auto px-4 py-8">
<div className="max-w-7xl mx-auto space-y-8"> <div className="max-w-7xl mx-auto space-y-8">
{/* Overall Statistics */} {/* Overall Statistics */}
<div className="grid grid-cols-1 md:grid-cols-5 gap-6"> <div className="grid grid-cols-2 md:grid-cols-5 gap-3 md:gap-6">
<Card> <Card>
<CardContent className="p-6 text-center"> <CardContent className="p-3 md:p-6 text-center">
<div className="w-12 h-12 bg-primary/10 rounded-full flex items-center justify-center mx-auto mb-3"> <div className="w-8 h-8 md:w-12 md:h-12 bg-primary/10 rounded-full flex items-center justify-center mx-auto mb-2 md:mb-3">
<Users className="w-6 h-6 text-primary" /> <Users className="w-4 h-4 md:w-6 md:h-6 text-primary" />
</div> </div>
<div className="text-2xl font-bold text-foreground mb-1">{overallStats.totalUsers}</div> <div className="text-lg md:text-2xl font-bold text-foreground mb-1">{overallStats.totalUsers}</div>
<div className="text-sm text-muted-foreground"></div> <div className="text-xs md:text-sm text-muted-foreground"></div>
</CardContent> </CardContent>
</Card> </Card>
<Card> <Card>
<CardContent className="p-6 text-center"> <CardContent className="p-3 md:p-6 text-center">
<div className="w-12 h-12 bg-blue-500/10 rounded-full flex items-center justify-center mx-auto mb-3"> <div className="w-8 h-8 md:w-12 md:h-12 bg-blue-500/10 rounded-full flex items-center justify-center mx-auto mb-2 md:mb-3">
<Target className="w-6 h-6 text-blue-500" /> <Target className="w-4 h-4 md:w-6 md:h-6 text-blue-500" />
</div> </div>
<div className="text-2xl font-bold text-foreground mb-1">{overallStats.totalParticipants}</div> <div className="text-lg md:text-2xl font-bold text-foreground mb-1">{overallStats.totalParticipants}</div>
<div className="text-sm text-muted-foreground"></div> <div className="text-xs md:text-sm text-muted-foreground"></div>
</CardContent> </CardContent>
</Card> </Card>
<Card> <Card>
<CardContent className="p-6 text-center"> <CardContent className="p-3 md:p-6 text-center">
<div className="w-12 h-12 bg-green-500/10 rounded-full flex items-center justify-center mx-auto mb-3"> <div className="w-8 h-8 md:w-12 md:h-12 bg-green-500/10 rounded-full flex items-center justify-center mx-auto mb-2 md:mb-3">
<TrendingUp className="w-6 h-6 text-green-500" /> <TrendingUp className="w-4 h-4 md:w-6 md:h-6 text-green-500" />
</div> </div>
<div className="text-2xl font-bold text-foreground mb-1">{overallStats.overallParticipationRate}%</div> <div className="text-lg md:text-2xl font-bold text-foreground mb-1">{overallStats.overallParticipationRate}%</div>
<div className="text-sm text-muted-foreground"></div> <div className="text-xs md:text-sm text-muted-foreground"></div>
</CardContent> </CardContent>
</Card> </Card>
<Card> <Card>
<CardContent className="p-6 text-center"> <CardContent className="p-3 md:p-6 text-center">
<div className="w-12 h-12 bg-accent/10 rounded-full flex items-center justify-center mx-auto mb-3"> <div className="w-8 h-8 md:w-12 md:h-12 bg-accent/10 rounded-full flex items-center justify-center mx-auto mb-2 md:mb-3">
<Award className="w-6 h-6 text-accent" /> <Award className="w-4 h-4 md:w-6 md:h-6 text-accent" />
</div> </div>
<div className="text-2xl font-bold text-foreground mb-1">{overallStats.averageScore}</div> <div className="text-lg md:text-2xl font-bold text-foreground mb-1">{overallStats.averageScore}</div>
<div className="text-sm text-muted-foreground"></div> <div className="text-xs md:text-sm text-muted-foreground"></div>
</CardContent> </CardContent>
</Card> </Card>
<Card> <Card>
<CardContent className="p-6 text-center"> <CardContent className="p-3 md:p-6 text-center">
<div className="w-12 h-12 bg-purple-500/10 rounded-full flex items-center justify-center mx-auto mb-3"> <div className="w-8 h-8 md:w-12 md:h-12 bg-purple-500/10 rounded-full flex items-center justify-center mx-auto mb-2 md:mb-3">
<BarChart3 className="w-6 h-6 text-purple-500" /> <BarChart3 className="w-4 h-4 md:w-6 md:h-6 text-purple-500" />
</div> </div>
<div className="text-2xl font-bold text-foreground mb-1">{overallStats.totalTests}</div> <div className="text-lg md:text-2xl font-bold text-foreground mb-1">{overallStats.totalTests}</div>
<div className="text-sm text-muted-foreground"></div> <div className="text-xs md:text-sm text-muted-foreground"></div>
</CardContent> </CardContent>
</Card> </Card>
</div> </div>

View File

@@ -237,9 +237,9 @@ function AdminResultsContent() {
const link = document.createElement('a') const link = document.createElement('a')
link.href = url link.href = url
link.download = data.filename link.download = data.filename
document.body.appendChild(link) document.body.appendChild(link)
link.click() link.click()
document.body.removeChild(link) document.body.removeChild(link)
window.URL.revokeObjectURL(url) window.URL.revokeObjectURL(url)
} else { } else {
console.error('匯出失敗:', data.message) console.error('匯出失敗:', data.message)
@@ -299,44 +299,44 @@ function AdminResultsContent() {
<div className="container mx-auto px-4 py-8"> <div className="container mx-auto px-4 py-8">
<div className="max-w-7xl mx-auto space-y-8"> <div className="max-w-7xl mx-auto space-y-8">
{/* Summary Cards */} {/* Summary Cards */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-6"> <div className="grid grid-cols-2 md:grid-cols-4 gap-3 md:gap-6">
<Card> <Card>
<CardContent className="p-6 text-center"> <CardContent className="p-3 md:p-6 text-center">
<div className="w-12 h-12 bg-primary/10 rounded-full flex items-center justify-center mx-auto mb-3"> <div className="w-8 h-8 md:w-12 md:h-12 bg-primary/10 rounded-full flex items-center justify-center mx-auto mb-2 md:mb-3">
<BarChart3 className="w-6 h-6 text-primary" /> <BarChart3 className="w-4 h-4 md:w-6 md:h-6 text-primary" />
</div> </div>
<div className="text-2xl font-bold text-foreground mb-1">{stats.totalResults}</div> <div className="text-lg md:text-2xl font-bold text-foreground mb-1">{stats.totalResults}</div>
<div className="text-sm text-muted-foreground"></div> <div className="text-xs md:text-sm text-muted-foreground"></div>
</CardContent> </CardContent>
</Card> </Card>
<Card> <Card>
<CardContent className="p-6 text-center"> <CardContent className="p-3 md:p-6 text-center">
<div className="w-12 h-12 bg-blue-500/10 rounded-full flex items-center justify-center mx-auto mb-3"> <div className="w-8 h-8 md:w-12 md:h-12 bg-blue-500/10 rounded-full flex items-center justify-center mx-auto mb-2 md:mb-3">
<Brain className="w-6 h-6 text-blue-500" /> <Brain className="w-4 h-4 md:w-6 md:h-6 text-blue-500" />
</div> </div>
<div className="text-2xl font-bold text-foreground mb-1">{stats.averageScore}</div> <div className="text-lg md:text-2xl font-bold text-foreground mb-1">{stats.averageScore}</div>
<div className="text-sm text-muted-foreground"></div> <div className="text-xs md:text-sm text-muted-foreground"></div>
</CardContent> </CardContent>
</Card> </Card>
<Card> <Card>
<CardContent className="p-6 text-center"> <CardContent className="p-3 md:p-6 text-center">
<div className="w-12 h-12 bg-green-500/10 rounded-full flex items-center justify-center mx-auto mb-3"> <div className="w-8 h-8 md:w-12 md:h-12 bg-green-500/10 rounded-full flex items-center justify-center mx-auto mb-2 md:mb-3">
<Lightbulb className="w-6 h-6 text-green-500" /> <Lightbulb className="w-4 h-4 md:w-6 md:h-6 text-green-500" />
</div> </div>
<div className="text-2xl font-bold text-foreground mb-1">{stats.totalUsers}</div> <div className="text-lg md:text-2xl font-bold text-foreground mb-1">{stats.totalUsers}</div>
<div className="text-sm text-muted-foreground"></div> <div className="text-xs md:text-sm text-muted-foreground"></div>
</CardContent> </CardContent>
</Card> </Card>
<Card> <Card>
<CardContent className="p-6 text-center"> <CardContent className="p-3 md:p-6 text-center">
<div className="w-12 h-12 bg-purple-500/10 rounded-full flex items-center justify-center mx-auto mb-3"> <div className="w-8 h-8 md:w-12 md:h-12 bg-purple-500/10 rounded-full flex items-center justify-center mx-auto mb-2 md:mb-3">
<BarChart3 className="w-6 h-6 text-purple-500" /> <BarChart3 className="w-4 h-4 md:w-6 md:h-6 text-purple-500" />
</div> </div>
<div className="text-2xl font-bold text-foreground mb-1">{stats.participationRate}%</div> <div className="text-lg md:text-2xl font-bold text-foreground mb-1">{stats.participationRate}%</div>
<div className="text-sm text-muted-foreground"></div> <div className="text-xs md:text-sm text-muted-foreground"></div>
</CardContent> </CardContent>
</Card> </Card>
</div> </div>
@@ -431,17 +431,17 @@ function AdminResultsContent() {
) : ( ) : (
<> <>
<Table> <Table>
<TableHeader> <TableHeader>
<TableRow> <TableRow>
<TableHead></TableHead> <TableHead></TableHead>
<TableHead></TableHead> <TableHead></TableHead>
<TableHead></TableHead> <TableHead></TableHead>
<TableHead></TableHead> <TableHead></TableHead>
<TableHead></TableHead> <TableHead></TableHead>
<TableHead></TableHead> <TableHead></TableHead>
<TableHead></TableHead> <TableHead></TableHead>
</TableRow> </TableRow>
</TableHeader> </TableHeader>
<TableBody> <TableBody>
{results.map((result) => { {results.map((result) => {
const testTypeInfo = getTestTypeInfo(result.type) const testTypeInfo = getTestTypeInfo(result.type)
@@ -475,7 +475,7 @@ function AdminResultsContent() {
{scoreLevel.level} {scoreLevel.level}
</Badge> </Badge>
</TableCell> </TableCell>
<TableCell> <TableCell>
<div className="text-sm">{formatDate(result.completedAt)}</div> <div className="text-sm">{formatDate(result.completedAt)}</div>
</TableCell> </TableCell>
<TableCell> <TableCell>
@@ -488,8 +488,8 @@ function AdminResultsContent() {
<Eye className="w-4 h-4" /> <Eye className="w-4 h-4" />
</Button> </Button>
</TableCell> </TableCell>
</TableRow> </TableRow>
) )
})} })}
</TableBody> </TableBody>
@@ -644,7 +644,7 @@ function AdminResultsContent() {
{/* 詳細結果模態框 */} {/* 詳細結果模態框 */}
<Dialog open={showDetailModal} onOpenChange={setShowDetailModal}> <Dialog open={showDetailModal} onOpenChange={setShowDetailModal}>
<DialogContent className="max-w-4xl max-h-[80vh] overflow-y-auto"> <DialogContent className="max-w-4xl max-h-[80vh] overflow-y-auto w-[95vw] max-w-[95vw] sm:w-auto sm:max-w-4xl">
<DialogHeader> <DialogHeader>
<DialogTitle></DialogTitle> <DialogTitle></DialogTitle>
<DialogDescription> <DialogDescription>
@@ -665,7 +665,7 @@ function AdminResultsContent() {
<CardTitle></CardTitle> <CardTitle></CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4">
<div> <div>
<label className="text-sm font-medium text-muted-foreground"></label> <label className="text-sm font-medium text-muted-foreground"></label>
<p className="text-sm">{detailData.user.name}</p> <p className="text-sm">{detailData.user.name}</p>
@@ -715,43 +715,43 @@ function AdminResultsContent() {
{detailData.questions {detailData.questions
.filter((q: any) => q.type === 'logic') .filter((q: any) => q.type === 'logic')
.map((question: any, index: number) => ( .map((question: any, index: number) => (
<div key={index} className="border rounded-lg p-4 bg-blue-50/30"> <div key={index} className="border rounded-lg p-3 sm:p-4 bg-blue-50/30">
<div className="flex items-start justify-between mb-3"> <div className="flex items-start justify-between mb-2 sm:mb-3">
<h4 className="font-medium"> {index + 1} </h4> <h4 className="font-medium text-sm sm:text-base"> {index + 1} </h4>
<Badge variant={question.isCorrect ? "default" : "destructive"}> <Badge variant={question.isCorrect ? "default" : "destructive"} className="text-xs">
{question.isCorrect ? "正確" : "錯誤"} {question.isCorrect ? "正確" : "錯誤"}
</Badge> </Badge>
</div> </div>
<div className="space-y-3"> <div className="space-y-2 sm:space-y-3">
<div> <div>
<label className="text-sm font-medium text-muted-foreground"></label> <label className="text-sm font-medium text-muted-foreground"></label>
<p className="text-sm mt-1">{question.question}</p> <p className="text-xs sm:text-sm mt-1 break-words">{question.question}</p>
</div> </div>
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4">
<div> <div>
<label className="text-sm font-medium text-muted-foreground"></label> <label className="text-sm font-medium text-muted-foreground"></label>
<div className="space-y-1 mt-1"> <div className="space-y-1 mt-1">
{question.option_a && <p className="text-sm">A. {question.option_a}</p>} {question.option_a && <p className="text-xs sm:text-sm break-words">A. {question.option_a}</p>}
{question.option_b && <p className="text-sm">B. {question.option_b}</p>} {question.option_b && <p className="text-xs sm:text-sm break-words">B. {question.option_b}</p>}
{question.option_c && <p className="text-sm">C. {question.option_c}</p>} {question.option_c && <p className="text-xs sm:text-sm break-words">C. {question.option_c}</p>}
{question.option_d && <p className="text-sm">D. {question.option_d}</p>} {question.option_d && <p className="text-xs sm:text-sm break-words">D. {question.option_d}</p>}
{question.option_e && <p className="text-sm">E. {question.option_e}</p>} {question.option_e && <p className="text-xs sm:text-sm break-words">E. {question.option_e}</p>}
</div> </div>
</div> </div>
<div> <div>
<label className="text-sm font-medium text-muted-foreground"></label> <label className="text-sm font-medium text-muted-foreground"></label>
<div className="space-y-1 mt-1"> <div className="space-y-1 mt-1">
<p className="text-sm">: <span className="font-bold">{question.userAnswer}</span></p> <p className="text-xs sm:text-sm">: <span className="font-bold">{question.userAnswer}</span></p>
<p className="text-sm">: <span className="font-bold text-green-600">{question.correctAnswer}</span></p> <p className="text-xs sm:text-sm">: <span className="font-bold text-green-600">{question.correctAnswer}</span></p>
</div> </div>
</div> </div>
</div> </div>
{question.explanation && ( {question.explanation && (
<div> <div>
<label className="text-sm font-medium text-muted-foreground"></label> <label className="text-sm font-medium text-muted-foreground"></label>
<p className="text-sm mt-1">{question.explanation}</p> <p className="text-xs sm:text-sm mt-1 break-words">{question.explanation}</p>
</div> </div>
)} )}
</div> </div>
@@ -772,28 +772,28 @@ function AdminResultsContent() {
{detailData.questions {detailData.questions
.filter((q: any) => q.type === 'creative') .filter((q: any) => q.type === 'creative')
.map((question: any, index: number) => ( .map((question: any, index: number) => (
<div key={index} className="border rounded-lg p-4 bg-green-50/30"> <div key={index} className="border rounded-lg p-3 sm:p-4 bg-green-50/30">
<div className="flex items-start justify-between mb-3"> <div className="flex items-start justify-between mb-2 sm:mb-3">
<h4 className="font-medium"> {index + 1} </h4> <h4 className="font-medium text-sm sm:text-base"> {index + 1} </h4>
<Badge variant="outline" className="text-green-600 border-green-600"> <Badge variant="outline" className="text-green-600 border-green-600 text-xs">
{question.score} {question.score}
</Badge> </Badge>
</div> </div>
<div className="space-y-3"> <div className="space-y-2 sm:space-y-3">
<div> <div>
<label className="text-sm font-medium text-muted-foreground"></label> <label className="text-sm font-medium text-muted-foreground"></label>
<p className="text-sm mt-1">{question.statement}</p> <p className="text-xs sm:text-sm mt-1 break-words">{question.statement}</p>
</div> </div>
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4">
<div> <div>
<label className="text-sm font-medium text-muted-foreground"></label> <label className="text-sm font-medium text-muted-foreground"></label>
<p className="text-sm mt-1">{question.userAnswer}</p> <p className="text-xs sm:text-sm mt-1">{question.userAnswer}</p>
</div> </div>
<div> <div>
<label className="text-sm font-medium text-muted-foreground"></label> <label className="text-sm font-medium text-muted-foreground"></label>
<p className="text-sm mt-1 font-bold">{question.score} </p> <p className="text-xs sm:text-sm mt-1 font-bold">{question.score} </p>
</div> </div>
</div> </div>
</div> </div>