Skip to content
Open
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
12 changes: 12 additions & 0 deletions members/kalinuxJS/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Web3 前端训练营报名

## 个人信息

* GitHub ID: kalinuxJS
* OpenBuild Username:
* ERC20 钱包地址: (首次如果没有,学习完毕钱包在填写)

### 个人介绍

20年毕业、曾就职于中科院以及虎扑
前端技术栈react\next\vue\微信小程序\node.js
24 changes: 24 additions & 0 deletions members/kalinuxJS/task1/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
69 changes: 69 additions & 0 deletions members/kalinuxJS/task1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

## Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:

```js
export default tseslint.config([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...

// Remove tseslint.configs.recommended and replace with this
...tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
...tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
...tseslint.configs.stylisticTypeChecked,

// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```

You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:

```js
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'

export default tseslint.config([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```
23 changes: 23 additions & 0 deletions members/kalinuxJS/task1/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { globalIgnores } from 'eslint/config'

export default tseslint.config([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs['recommended-latest'],
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
},
])
13 changes: 13 additions & 0 deletions members/kalinuxJS/task1/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
29 changes: 29 additions & 0 deletions members/kalinuxJS/task1/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "task1",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"react": "^19.1.1",
"react-dom": "^19.1.1"
},
"devDependencies": {
"@eslint/js": "^9.33.0",
"@types/react": "^19.1.10",
"@types/react-dom": "^19.1.7",
"@vitejs/plugin-react": "^5.0.0",
"eslint": "^9.33.0",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20",
"globals": "^16.3.0",
"typescript": "~5.8.3",
"typescript-eslint": "^8.39.1",
"vite": "^7.1.2"
}
}
1 change: 1 addition & 0 deletions members/kalinuxJS/task1/public/vite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions members/kalinuxJS/task1/src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}

.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}

@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}

.card {
padding: 2em;
}

.read-the-docs {
color: #888;
}
49 changes: 49 additions & 0 deletions members/kalinuxJS/task1/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { useState, useEffect } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
import Header from './components/header'
import ToDoList from './components/toDoList'
import AddToDo from './components/addToDo'

// 定义待办事项的类型
interface TodoItem {
content: string;
completed: boolean;
}

function App() {
// 从本地存储初始化状态,如果没有则使用空数组
const [list, setList] = useState<TodoItem[]>(() => {
const savedTodos = localStorage.getItem('todos');
return savedTodos ? JSON.parse(savedTodos) : [];
});

// 添加任务
const addTask = (task: TodoItem) => {
setList([...list, task]);
}

// 更新列表(用于完成和删除操作)
const changeList = (newList: TodoItem[]) => {
setList(newList);
}

// 使用 useEffect 监听 list 变化,自动保存到本地存储
useEffect(() => {
localStorage.setItem('todos', JSON.stringify(list));
console.log('待办事项已保存到本地存储:', list);
}, [list]);

return (
<>
<div>
<Header title="Todo-List" />
<ToDoList list={list} changeList={changeList} />
<AddToDo addTask={addTask} />
</div>
</>
)
}

export default App
1 change: 1 addition & 0 deletions members/kalinuxJS/task1/src/assets/react.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions members/kalinuxJS/task1/src/components/addToDo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useState } from 'react'

interface TodoItem {
content: string;
completed: boolean;
}

const AddToDo = ({
addTask,
}: {
addTask: (task: TodoItem) => void
}) => {
const [content, setContent] = useState<string>('')

const handleAdd = () => {
if (content.trim()) { // 检查输入内容不为空
addTask({content: content.trim(), completed: false})
setContent('') // 清空输入框
}
}

const handleKeyPress = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
handleAdd()
}
}

return (
<div>
<input
type="text"
value={content}
onChange={(e) => setContent(e.target.value)}
onKeyPress={handleKeyPress}
placeholder="请输入任务内容"
/>
<button onClick={handleAdd} style={{margin: '0 10px',height: '30px',width: '60px',fontSize: '12px'}}>添加</button>
</div>
)
}

export default AddToDo;
13 changes: 13 additions & 0 deletions members/kalinuxJS/task1/src/components/header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const Header = ({
title,
}: {
title: string;
}) => {
return (
<div>
<h1>{title}</h1>
</div>
)
}

export default Header;
43 changes: 43 additions & 0 deletions members/kalinuxJS/task1/src/components/toDoList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

interface TodoItem {
content: string;
completed: boolean;
}

interface TodoListProps {
list: TodoItem[];
changeList: (list: TodoItem[]) => void;
}

const ToDoList = ({list, changeList}: TodoListProps) => {
const handleComplete = (index: number) => {
const newList = [...list]; // 创建新数组,避免直接修改原数组
newList[index].completed = !newList[index].completed;
changeList(newList);
}

const handleDelete = (index: number) => {
const newList = [...list]; // 创建新数组,避免直接修改原数组
newList.splice(index, 1);
changeList(newList);
}

return (
<div>
{list.map((item, index) => (
<div key={`${item.content}-${index}`}>
<span>{item.content}</span>
<span style={{color: item.completed ? 'green' : 'red', margin: '0 10px'}}>{item.completed ? '已完成' : '未完成'}</span>
<button onClick={() => handleComplete(index)} style={{margin: '0 10px',height: '30px',width: '100px',fontSize: '12px'}}>
{item.completed ? '未完成' : '完成'}
</button>
<button onClick={() => handleDelete(index)} style={{margin: '0 10px',height: '30px',width: '60px',fontSize: '12px',color: 'red'}}>
Delete
</button>
</div>
))}
</div>
)
}

export default ToDoList;
Loading