Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions .env.example

This file was deleted.

18 changes: 10 additions & 8 deletions app/api/crates/route.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
// /home/rust/workspace/cratespro-frontend/app/api/programs/route.ts
import { NextRequest, NextResponse } from 'next/server';
import pool from '../../lib/db';

export async function GET(req: NextRequest) {
try {
const client = await pool.connect();
const res = await client.query('SELECT name, description FROM programs');
client.release();
// 发送 HTTP 请求获取外部数据
const externalApiUrl = 'http://210.28.134.203:6888/crates'; // 替换为你的外部 API URL
const externalRes = await fetch(externalApiUrl);

const programs = res.rows;
if (!externalRes.ok) {
throw new Error('Failed to fetch external data');
}

return NextResponse.json(programs);
const externalData = await externalRes.json();

return NextResponse.json(externalData);
} catch (error) {
console.error('Database query error:', error);
console.error('Error:', error);
return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
}
}
35 changes: 19 additions & 16 deletions app/api/submit/route.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
import { NextRequest, NextResponse } from 'next/server';
import pool from '../../lib/db'; // 导入数据库连接池
import { NextResponse } from 'next/server';

export async function POST(req: NextRequest) {
try {
const { content } = await req.json(); // 解析请求体中的 JSON 数据
export async function POST(request: { json: () => any; }) {
const apiUrl = process.env.API_URL; // 读取环境变量,获取后端服务的基础 URL
const body = await request.json(); // 解析请求体

if (!content) {
return NextResponse.json({ error: '内容不能为空' }, { status: 400 });
try {
const response = await fetch(`${apiUrl}/submit`, { //向后端发送服务请求
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(body), // 将请求体发送到后端
});
//请求失败直接返回
if (!response.ok) {
return NextResponse.json({ error: 'Failed to submit data' }, { status: 500 });
}

const client = await pool.connect(); // 获取数据库连接
// 假设我们将内容插入到名为 'submissions' 的表中
await client.query('INSERT INTO submissions (content) VALUES ($1)', [content]);
client.release(); // 释放连接

return NextResponse.json({ message: '内容提交成功!' }, { status: 200 });
//解析成功的响应
const result = await response.json();
return NextResponse.json({ message: 'Submission successful', data: result });
} catch (error) {
console.error('提交错误:', error);
return NextResponse.json({ error: '内部服务器错误' }, { status: 500 });
return NextResponse.json({ error: 'An error occurred while submitting data.' }, { status: 500 });
}
}
2 changes: 0 additions & 2 deletions app/programs/[name]/[version]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,12 @@ import SecurityAdvisories from '../../../../components/SecurityAdvisories';
import BenchmarkResults from '../../../../components/BenchmarkResults';
import VersionsSelector from '../../../../components/VersionsSelector';
import { CrateInfo } from '@/app/lib/crate_info';

//异步获取依赖树
async function fetchDependencyTree(name: string, version: string) {
const response = await fetch(`/api/crates/${name}/${version}`);
const versionData = await response.json();

const dependencies = versionData.dependencies || [];

const dependenciesDetails = await Promise.all(dependencies.map(async (subDep: { name: string; version: string; }) => {
return fetchDependencyTree(subDep.name, subDep.version);
}));
Expand Down
27 changes: 17 additions & 10 deletions app/ui/programs/nav-links.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { useState } from 'react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import clsx from 'clsx';
import React from 'react';
import { message } from 'antd';

// Map of links to display in the side navigation.
// Depending on the size of the application, this would be stored in a database.
Expand All @@ -23,18 +25,17 @@ const links = [
// { name: 'Customers', href: '/dashboard/customers', icon: UserGroupIcon },
];

export default function NavLinks() {
const NavLinks: React.FC = () => {
const pathname = usePathname();
const [isModalOpen, setModalOpen] = useState(false);
const [inputValue, setInputValue] = useState('');

const [file, setFile] = useState<File | null>(null);
const [isGithubLink, setIsGithubLink] = useState(true); // 控制输入类型
const [messageApi, contextHolder] = message.useMessage();//antd-message的hooks调用

//暂定上传数据类型为react表单类型
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();

const formData = new FormData();
if (isGithubLink) {
formData.append('githubLink', inputValue);
Expand All @@ -44,29 +45,33 @@ export default function NavLinks() {

try {
//用fetch向服务器发声POST请求,提交用户输入的内容
const response = await fetch('/api/submi', { // 待替换为服务器API
const response = await fetch('/api/submit', { //待替换为后端服务API
method: 'POST',
//请求体,将对象转换为json字符串
//请求体
body: formData,
});
//console.log('Response:', response); // 输出响应

//响应处理,根据响应结果显示提示信息,并重置输入框或关闭弹窗
if (response.ok) {
alert('内容提交成功!');//提交成功后重置输入框的值,并关闭弹窗
messageApi.success('提交成功');//提交成功后重置输入框的值,并关闭弹窗
console.log('提交成功');
setInputValue('');
setFile(null);
setModalOpen(false);
} else {
alert('提交失败请重试。');
messageApi.error('提交失败,请重试', 2);
}
} catch (error) {
console.error('提交错误:', error);
alert('提交失败,请检查网络连接。');
messageApi.error('提交失败,请检查网络连接');
//console.log('提交失败,请检查网络连接。', error);
}
};

//渲染部分
return (
<>
{contextHolder}
{links.map((link) => {
const LinkIcon = link.icon;
return (
Expand Down Expand Up @@ -185,4 +190,6 @@ export default function NavLinks() {
)}
</>
);
}
}

export default NavLinks;
48 changes: 48 additions & 0 deletions components/MessageContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// MessageContext.tsx
import React, { createContext, useContext, ReactNode } from 'react';
import { message } from 'antd';

// 定义消息上下文的类型
interface MessageContextType {
success: () => void;
error: () => void;
warning: () => void;
}

// 创建上下文,默认值为 null
const MessageContext = createContext<MessageContextType | null>(null);

// 定义 MessageProvider 的属性类型
interface MessageProviderProps {
children: ReactNode; // 允许任意子元素
}

// 创建 MessageProvider 组件
export const MessageProvider: React.FC<MessageProviderProps> = ({ children }) => {
const success = () => {
message.success('这是一个成功消息!');
};

const error = () => {
message.error('这是一个错误消息!');
};

const warning = () => {
message.warning('这是一个警告消息!');
};

return (
<MessageContext.Provider value={{ success, error, warning }}>
{children}
</MessageContext.Provider>
);
};

// 自定义 hook 使用上下文
export const useMessage = () => {
const context = useContext(MessageContext);
if (!context) {
throw new Error('useMessage must be used within a MessageProvider');
}
return context;
};
3 changes: 2 additions & 1 deletion layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import '@/app/ui/global.css';
import { inter } from '@/app/ui/fonts';

import React from 'react';
import { message } from 'antd';

export default function RootLayout({
children,
Expand Down
Loading