Переглянути джерело

Product Management System with TypeScript, React, and Vite

Message ID: omNZePw
zyh 1 рік тому
батько
коміт
99e6f416ec
7 змінених файлів з 138 додано та 16 видалено
  1. 10 9
      index.html
  2. 7 7
      package.json
  3. 26 0
      src/App.tsx
  4. 51 0
      src/components/AddProductForm.tsx
  5. 29 0
      src/components/ProductList.tsx
  6. 10 0
      src/main.tsx
  7. 5 0
      src/types.ts

+ 10 - 9
index.html

@@ -1,12 +1,13 @@
 <!DOCTYPE html>
 <html lang="en">
-  <head>
-    <meta charset="UTF-8" />
-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>会友信息管理系统</title>
-  </head>
-  <body>
-    <div id="root"></div>
-    <script type="module" src="/src/main.jsx"></script>
-  </body>
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>Product Management System</title>
+  <link rel="stylesheet" href="index.css">
+</head>
+<body>
+  <div id="root"></div>
+  <script type="module" src="src/main.tsx"></script>
+</body>
 </html>

+ 7 - 7
package.json

@@ -1,22 +1,22 @@
 {
-  "name": "member-management-system",
+  "name": "product-management-system",
   "private": true,
-  "version": "0.1.0",
+  "version": "0.0.0",
   "type": "module",
   "scripts": {
     "dev": "vite",
-    "build": "vite build",
+    "build": "tsc && vite build",
     "preview": "vite preview"
   },
   "dependencies": {
     "react": "^18.2.0",
-    "react-dom": "^18.2.0",
-    "xlsx": "^0.18.5"
+    "react-dom": "^18.2.0"
   },
   "devDependencies": {
     "@types/react": "^18.0.28",
     "@types/react-dom": "^18.0.11",
-    "@vitejs/plugin-react": "^3.1.0",
-    "vite": "^4.2.0"
+    "@vitejs/plugin-react": "^4.2.1",
+    "typescript": "^5.2.2",
+    "vite": "^5.1.4"
   }
 }

+ 26 - 0
src/App.tsx

@@ -0,0 +1,26 @@
+import React, { useState } from 'react';
+import ProductList from './components/ProductList';
+import AddProductForm from './components/AddProductForm';
+import { Product } from './types';
+
+const App: React.FC = () => {
+  const [products, setProducts] = useState<Product[]>([]);
+
+  const addProduct = (product: Product) => {
+    setProducts([...products, { ...product, id: Date.now() }]);
+  };
+
+  const deleteProduct = (id: number) => {
+    setProducts(products.filter(product => product.id !== id));
+  };
+
+  return (
+    <div className="container">
+      <h1>Product Management System</h1>
+      <AddProductForm onAddProduct={addProduct} />
+      <ProductList products={products} onDeleteProduct={deleteProduct} />
+    </div>
+  );
+};
+
+export default App;

+ 51 - 0
src/components/AddProductForm.tsx

@@ -0,0 +1,51 @@
+import React, { useState } from 'react';
+import { Product } from '../types';
+
+interface AddProductFormProps {
+  onAddProduct: (product: Product) => void;
+}
+
+const AddProductForm: React.FC<AddProductFormProps> = ({ onAddProduct }) => {
+  const [name, setName] = useState('');
+  const [price, setPrice] = useState('');
+
+  const handleSubmit = (e: React.FormEvent) => {
+    e.preventDefault();
+    if (name && price) {
+      onAddProduct({ name, price: parseFloat(price), id: 0 });
+      setName('');
+      setPrice('');
+    }
+  };
+
+  return (
+    <form onSubmit={handleSubmit}>
+      <h2>Add New Product</h2>
+      <div>
+        <label htmlFor="name">Name:</label>
+        <input
+          type="text"
+          id="name"
+          value={name}
+          onChange={(e) => setName(e.target.value)}
+          required
+        />
+      </div>
+      <div>
+        <label htmlFor="price">Price:</label>
+        <input
+          type="number"
+          id="price"
+          value={price}
+          onChange={(e) => setPrice(e.target.value)}
+          min="0"
+          step="0.01"
+          required
+        />
+      </div>
+      <button type="submit">Add Product</button>
+    </form>
+  );
+};
+
+export default AddProductForm;

+ 29 - 0
src/components/ProductList.tsx

@@ -0,0 +1,29 @@
+import React from 'react';
+import { Product } from '../types';
+
+interface ProductListProps {
+  products: Product[];
+  onDeleteProduct: (id: number) => void;
+}
+
+const ProductList: React.FC<ProductListProps> = ({ products, onDeleteProduct }) => {
+  return (
+    <div className="product-list">
+      <h2>Product List</h2>
+      {products.length === 0 ? (
+        <p>No products available.</p>
+      ) : (
+        <ul>
+          {products.map((product) => (
+            <li key={product.id}>
+              {product.name} - ${product.price}
+              <button onClick={() => onDeleteProduct(product.id)}>Delete</button>
+            </li>
+          ))}
+        </ul>
+      )}
+    </div>
+  );
+};
+
+export default ProductList;

+ 10 - 0
src/main.tsx

@@ -0,0 +1,10 @@
+import React from 'react'
+import ReactDOM from 'react-dom/client'
+import App from './App'
+import './index.css'
+
+ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
+  <React.StrictMode>
+    <App />
+  </React.StrictMode>,
+)

+ 5 - 0
src/types.ts

@@ -0,0 +1,5 @@
+export interface Product {
+  id: number;
+  name: string;
+  price: number;
+}