update
This commit is contained in:
parent
f78a466c39
commit
f727b212df
30
Dockerfile
Normal file
30
Dockerfile
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# Stage 1: Install dependencies
|
||||||
|
FROM node:18-alpine AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
RUN sed -i 's#https\?://dl-cdn.alpinelinux.org/alpine#https://mirrors.tuna.tsinghua.edu.cn/alpine#g' /etc/apk/repositories
|
||||||
|
RUN apk update
|
||||||
|
RUN npm config set registry https://registry.npmmirror.com
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
# Stage 2: Build the applicatio
|
||||||
|
COPY . .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Stage 3: Production image
|
||||||
|
FROM node:18-alpine AS runner
|
||||||
|
RUN mkdir -p /app/data && chmod 755 /app/data
|
||||||
|
WORKDIR /app
|
||||||
|
RUN sed -i 's#https\?://dl-cdn.alpinelinux.org/alpine#https://mirrors.tuna.tsinghua.edu.cn/alpine#g' /etc/apk/repositories
|
||||||
|
RUN apk update
|
||||||
|
ENV NODE_ENV Production
|
||||||
|
COPY --from=builder /app/next.config.js ./
|
||||||
|
COPY --from=builder /app/.next/standalone ./
|
||||||
|
COPY --from=builder /app/.next/static ./.next/static
|
||||||
|
COPY --from=builder /app/node_modules ./node_modules
|
||||||
|
COPY --from=builder /app/package*.json ./
|
||||||
|
COPY --from=builder /app/data/shorturl.db ./data
|
||||||
|
VOLUME /app/data
|
||||||
|
|
||||||
|
# Run App
|
||||||
|
CMD ["node", "server.js"]
|
@ -1,17 +1,11 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import yaml from 'yaml';
|
import yaml from 'yaml';
|
||||||
|
|
||||||
// 定义活动项的接口
|
|
||||||
interface ActivityParticipant {
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Activity {
|
interface Activity {
|
||||||
title: string;
|
title: string;
|
||||||
coverImage: string;
|
coverImage: string;
|
||||||
description: string;
|
description: string;
|
||||||
date: string;
|
date: string;
|
||||||
participants: ActivityParticipant[];
|
|
||||||
organizer: string;
|
organizer: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import './globals.css'
|
import './globals.css'
|
||||||
import { Inter } from 'next/font/google'
|
import { Inter } from 'next/font/google'
|
||||||
import Navbar from '@/components/Navbar'
|
import Navbar from '@/components/Navbar'
|
||||||
|
import Footer from '@/components/footer'
|
||||||
|
|
||||||
const inter = Inter({ subsets: ['latin'] })
|
const inter = Inter({ subsets: ['latin'] })
|
||||||
|
|
||||||
export const metadata = {
|
export const metadata = {
|
||||||
title: '影视星河摄影社团',
|
title: '影视星河',
|
||||||
description: '影视星河摄影社团官方网站',
|
description: '影视星河摄影社团官方网站',
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,6 +20,7 @@ export default function RootLayout({
|
|||||||
<body className={inter.className}>
|
<body className={inter.className}>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
{children}
|
{children}
|
||||||
|
<Footer />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
)
|
)
|
||||||
|
10
app/page.tsx
10
app/page.tsx
@ -36,7 +36,7 @@ export default function Home() {
|
|||||||
playsInline
|
playsInline
|
||||||
className="absolute top-0 left-0 w-full h-full object-cover"
|
className="absolute top-0 left-0 w-full h-full object-cover"
|
||||||
>
|
>
|
||||||
<source src="https://c.mmeiblog.cn/d/share/newbili/影视星河片头.mp4" type="video/mp4" />
|
<source src="https://c.mmeiblog.cn/d/share/newbili/%E5%BD%B1%E8%A7%86%E6%98%9F%E6%B2%B3%E7%89%87%E5%A4%B4.mp4" type="video/mp4" />
|
||||||
您的浏览器不支持视频标签。
|
您的浏览器不支持视频标签。
|
||||||
</video>
|
</video>
|
||||||
<div className="absolute top-0 left-0 w-full h-full bg-black opacity-50"></div>
|
<div className="absolute top-0 left-0 w-full h-full bg-black opacity-50"></div>
|
||||||
@ -67,13 +67,7 @@ export default function Home() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||||
{filteredActivities.map((activity, index) => (
|
{filteredActivities.map((activity, index) => (
|
||||||
<ActivityCard
|
<ActivityCard key={index} activity={activity} />
|
||||||
key={index}
|
|
||||||
activity={{
|
|
||||||
...activity,
|
|
||||||
participants: activity.participants.map(participant => participant.name)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { ChevronDown, ChevronUp } from 'lucide-react'
|
|
||||||
|
|
||||||
interface ActivityProps {
|
interface ActivityProps {
|
||||||
activity: {
|
activity: {
|
||||||
@ -10,13 +9,12 @@ interface ActivityProps {
|
|||||||
coverImage: string
|
coverImage: string
|
||||||
description: string
|
description: string
|
||||||
date: string
|
date: string
|
||||||
participants: string[]
|
|
||||||
organizer: string
|
organizer: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ActivityCard: React.FC<ActivityProps> = ({ activity }) => {
|
const ActivityCard: React.FC<ActivityProps> = ({ activity }) => {
|
||||||
const [isExpanded, setIsExpanded] = useState(false)
|
const [] = useState(false)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-white shadow-lg rounded-lg overflow-hidden">
|
<div className="bg-white shadow-lg rounded-lg overflow-hidden">
|
||||||
@ -33,45 +31,6 @@ const ActivityCard: React.FC<ActivityProps> = ({ activity }) => {
|
|||||||
<p className="text-gray-600 mb-2">{activity.description}</p>
|
<p className="text-gray-600 mb-2">{activity.description}</p>
|
||||||
<p className="text-sm text-gray-500 mb-2">日期:{activity.date}</p>
|
<p className="text-sm text-gray-500 mb-2">日期:{activity.date}</p>
|
||||||
<p className="text-sm text-gray-500 mb-2">组织者:{activity.organizer}</p>
|
<p className="text-sm text-gray-500 mb-2">组织者:{activity.organizer}</p>
|
||||||
<div className="mt-4">
|
|
||||||
<p className="text-sm font-semibold mb-1">参与者:</p>
|
|
||||||
{activity.participants.length <= 3 ? (
|
|
||||||
<ul className="list-disc list-inside">
|
|
||||||
{activity.participants.map((participant, index) => (
|
|
||||||
<li key={index} className="text-sm text-gray-600">{participant}</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
) : (
|
|
||||||
<div>
|
|
||||||
<ul className="list-disc list-inside">
|
|
||||||
{activity.participants.slice(0, 3).map((participant, index) => (
|
|
||||||
<li key={index} className="text-sm text-gray-600">{participant}</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
{isExpanded && (
|
|
||||||
<ul className="list-disc list-inside mt-2">
|
|
||||||
{activity.participants.slice(3).map((participant, index) => (
|
|
||||||
<li key={index + 3} className="text-sm text-gray-600">{participant}</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
)}
|
|
||||||
<button
|
|
||||||
className="mt-2 text-sm text-blue-600 hover:text-blue-800 flex items-center"
|
|
||||||
onClick={() => setIsExpanded(!isExpanded)}
|
|
||||||
>
|
|
||||||
{isExpanded ? (
|
|
||||||
<>
|
|
||||||
收起 <ChevronUp className="ml-1 w-4 h-4" />
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
展开更多 ({activity.participants.length - 3}) <ChevronDown className="ml-1 w-4 h-4" />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -115,7 +115,7 @@ export default function Device() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container mx-auto bg-white rounded-lg shadow-lg p-6 space-y-8">
|
<div className="container mx-auto bg-white rounded-lg shadow-lg p-6 space-y-8">
|
||||||
<h1 className="text-3xl font-bold text-center text-indigo-700 mb-8">摄影社团库存管理系统</h1>
|
<h1 className="text-3xl font-bold text-center text-indigo-700 mb-8">库存管理系统</h1>
|
||||||
<div className="flex justify-center space-x-4 mb-8">
|
<div className="flex justify-center space-x-4 mb-8">
|
||||||
<label className="bg-blue-500 text-white px-4 py-2 rounded-full cursor-pointer hover:bg-blue-600 transition duration-300">
|
<label className="bg-blue-500 text-white px-4 py-2 rounded-full cursor-pointer hover:bg-blue-600 transition duration-300">
|
||||||
导入数据
|
导入数据
|
||||||
|
50
components/footer.tsx
Normal file
50
components/footer.tsx
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
const Footer = () => {
|
||||||
|
const currentYear = new Date().getFullYear();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<footer className="footer">
|
||||||
|
<div className="container">
|
||||||
|
<p>
|
||||||
|
© {currentYear} 影视星河 版权所有
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
备案号:
|
||||||
|
<a href="http://www.beian.miit.gov.cn" target="_blank" rel="noopener noreferrer">
|
||||||
|
鲁ICP备12345678号-9
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
{/* 如果有公安备案,可以添加如下行 */}
|
||||||
|
{/* <p>
|
||||||
|
<a href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=1234567890123456"
|
||||||
|
target="_blank" rel="noopener noreferrer">
|
||||||
|
<img src="/path/to/police/beian.png" alt="公安备案图标"/>
|
||||||
|
粤公网安备 1234567890123456号
|
||||||
|
</a>
|
||||||
|
</p> */}
|
||||||
|
</div>
|
||||||
|
<style jsx>{`
|
||||||
|
.footer {
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
padding: 1rem 0;
|
||||||
|
text-align: center;
|
||||||
|
color: #6c757d;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 1200px;
|
||||||
|
}
|
||||||
|
.footer a {
|
||||||
|
color: #007bff;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.footer a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Footer;
|
@ -1,47 +1,26 @@
|
|||||||
activities:
|
activities:
|
||||||
- title: 月度摄影漫步
|
- title: 月度摄影漫步
|
||||||
coverImage: /images/photo-walk.jpg
|
coverImage: https://api.mmeiblog.cn/files/img/832582a1.jpg
|
||||||
description: 加入我们的月度城市摄影漫步。捕捉城市景观和街头场景。
|
description: 加入我们的月度城市摄影漫步。捕捉城市景观和街头场景。
|
||||||
date: 2023-07-15
|
date: 2023-07-15
|
||||||
participants:
|
|
||||||
- 张三
|
|
||||||
- 李四
|
|
||||||
- 王五
|
|
||||||
- 赵六
|
|
||||||
- 钱七
|
|
||||||
organizer: 刘老师
|
organizer: 刘老师
|
||||||
|
|
||||||
- title: 人像摄影工作坊
|
- title: 人像摄影工作坊
|
||||||
coverImage: /images/portrait-workshop.jpg
|
coverImage: https://api.mmeiblog.cn/files/img/01J95FFQDMJ1HSMQK7RDAD8S6A.jpg
|
||||||
description: 在专业摄影师的指导下,学习人像摄影的艺术。
|
description: 在专业摄影师的指导下,学习人像摄影的艺术。
|
||||||
date: 2023-07-22
|
date: 2023-07-22
|
||||||
participants:
|
|
||||||
- 陈一
|
|
||||||
- 周二
|
|
||||||
- 吴三
|
|
||||||
organizer: 黄教授
|
organizer: 黄教授
|
||||||
|
|
||||||
- title: 自然摄影探险
|
- title: 自然摄影探险
|
||||||
coverImage: /images/nature-expedition.jpg
|
coverImage: https://api.mmeiblog.cn/files/img/1718019633883.jpg
|
||||||
description: 探索大自然,在周末的自然摄影探险中捕捉壮丽的风景。
|
description: 探索大自然,在周末的自然摄影探险中捕捉壮丽的风景。
|
||||||
date: 2023-08-05
|
date: 2023-08-05
|
||||||
participants:
|
|
||||||
- 郑八
|
|
||||||
- 孙九
|
|
||||||
- 杨十
|
|
||||||
- 朱十一
|
|
||||||
- 秦十二
|
|
||||||
- 许十三
|
|
||||||
organizer: 林导师
|
organizer: 林导师
|
||||||
|
|
||||||
- title: 照片编辑大师班
|
- title: 照片编辑大师班
|
||||||
coverImage: /images/editing-masterclass.jpg
|
coverImage: /images/editing-masterclass.jpg
|
||||||
description: 通过我们的照片编辑大师班,使用行业标准软件提升您的后期处理技能。
|
description: 通过我们的照片编辑大师班,使用行业标准软件提升您的后期处理技能。
|
||||||
date: 2023-08-12
|
date: 2023-08-12
|
||||||
participants:
|
|
||||||
- 冯一
|
|
||||||
- 蒋二
|
|
||||||
- 沈三
|
|
||||||
organizer: 马老师
|
organizer: 马老师
|
||||||
|
|
||||||
showcase:
|
showcase:
|
||||||
|
11
next.config.js
Normal file
11
next.config.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/** @type {import('next').NextConfig} */
|
||||||
|
const nextConfig = {
|
||||||
|
images: {
|
||||||
|
domains: ['api.mmeiblog.cn'],
|
||||||
|
},
|
||||||
|
output: 'standalone',
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = nextConfig
|
||||||
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
|||||||
/** @type {import('next').NextConfig} */
|
|
||||||
const nextConfig = {};
|
|
||||||
|
|
||||||
export default nextConfig;
|
|
@ -3,7 +3,6 @@ export interface Activity {
|
|||||||
coverImage: string
|
coverImage: string
|
||||||
description: string
|
description: string
|
||||||
date: string
|
date: string
|
||||||
participants: string[]
|
|
||||||
organizer: string
|
organizer: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user