NewCourse.tsx 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import { ArrowLeft, ArrowRight } from 'lucide-react'
  2. import { FormEvent, useState } from 'react'
  3. import { Link, useNavigate } from 'react-router-dom'
  4. import { api } from '../api'
  5. export function NewCourse() {
  6. const navigate = useNavigate()
  7. const [busy, setBusy] = useState(false)
  8. const [error, setError] = useState('')
  9. async function submit(e: FormEvent<HTMLFormElement>) {
  10. e.preventDefault()
  11. setBusy(true)
  12. const f = new FormData(e.currentTarget)
  13. try {
  14. const { course } = await api.createCourse({
  15. name: String(f.get('name')),
  16. category: String(f.get('category')),
  17. audience: '',
  18. description: String(f.get('description')),
  19. })
  20. navigate(`/courses/${course.id}`)
  21. } catch (x) {
  22. setError((x as Error).message)
  23. } finally {
  24. setBusy(false)
  25. }
  26. }
  27. return (
  28. <div className="page form-page">
  29. <Link to="/" className="back-link">
  30. <ArrowLeft size={16} />返回课程
  31. </Link>
  32. <div className="form-layout">
  33. <aside>
  34. <span className="step-number">01</span>
  35. <p className="eyebrow">创建课程</p>
  36. <h1>
  37. 先告诉我们,<br />
  38. 这是一门什么课。
  39. </h1>
  40. <p>填写基本信息后,可添加课程资产和讲师,也可以直接跳过。</p>
  41. </aside>
  42. <form className="paper-form" onSubmit={submit}>
  43. <div className="form-title">
  44. <span>COURSE PROFILE</span>
  45. <h2>课程基本信息</h2>
  46. </div>
  47. <label>
  48. 课程名称 <b>*</b>
  49. <input name="name" required maxLength={100} />
  50. </label>
  51. <label>
  52. 课程分类
  53. <select name="category" defaultValue="党政专题">
  54. <option>党政专题</option>
  55. <option>高校公开课</option>
  56. <option>企业培训</option>
  57. <option>职业教育</option>
  58. <option>其他</option>
  59. </select>
  60. </label>
  61. <label>
  62. 课程简介
  63. <textarea name="description" rows={4} maxLength={500} />
  64. </label>
  65. {error && <p className="form-error">{error}</p>}
  66. <div className="form-footer">
  67. <span>下一步:课程资产与讲师</span>
  68. <button className="primary-button" disabled={busy}>
  69. {busy ? '正在创建…' : '继续'}
  70. <ArrowRight size={17} />
  71. </button>
  72. </div>
  73. </form>
  74. </div>
  75. </div>
  76. )
  77. }