PluginCard.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. import React, { useState } from 'react';
  2. import Link from 'next/link';
  3. import { toastSuccess, toastError } from '~/client/util/apiNotification';
  4. import { apiv3Post } from '~/client/util/apiv3-client';
  5. import { useSWRxPlugin } from '~/stores/plugin';
  6. import styles from './PluginCard.module.scss';
  7. type Props = {
  8. id: string,
  9. name: string,
  10. url: string,
  11. description: string,
  12. }
  13. export const PluginCard = (props: Props): JSX.Element => {
  14. const {
  15. id, name, url, description,
  16. } = props;
  17. const { data, mutate } = useSWRxPlugin(id);
  18. if (data == null) {
  19. return <></>;
  20. }
  21. const PluginCardButton = (): JSX.Element => {
  22. const [isEnabled, setState] = useState<boolean>(data.data.isEnabled);
  23. const onChangeHandler = async() => {
  24. const reqUrl = '/plugins/switch-isenabled';
  25. try {
  26. const res = await apiv3Post(reqUrl, { _id: id });
  27. setState(res.data.isEnabled);
  28. const pluginState = !isEnabled ? 'Enabled' : 'Disabled';
  29. toastSuccess(`${pluginState} Plugin `);
  30. }
  31. catch (err) {
  32. toastError('pluginIsEnabled', err);
  33. }
  34. finally {
  35. mutate();
  36. }
  37. };
  38. return (
  39. <div className={`${styles.plugin_card}`}>
  40. <div className="switch">
  41. <label className="switch__label">
  42. <input
  43. type="checkbox"
  44. className="switch__input"
  45. onChange={() => onChangeHandler()}
  46. checked={isEnabled}
  47. />
  48. <span className="switch__content"></span>
  49. <span className="switch__circle"></span>
  50. </label>
  51. </div>
  52. </div>
  53. );
  54. };
  55. const PluginDeleteButton = (): JSX.Element => {
  56. const onClickPluginDeleteBtnHandler = async() => {
  57. const reqUrl = '/plugins/deleted';
  58. try {
  59. await apiv3Post(reqUrl, { _id: id, name });
  60. toastSuccess(`${name} Deleted`);
  61. }
  62. catch (err) {
  63. toastError('pluginDelete', err);
  64. }
  65. finally {
  66. mutate();
  67. }
  68. };
  69. return (
  70. <div className="">
  71. <button
  72. type="submit"
  73. className="btn btn-primary"
  74. onClick={() => onClickPluginDeleteBtnHandler()}
  75. >
  76. Delete
  77. </button>
  78. </div>
  79. );
  80. };
  81. return (
  82. <div className="card shadow border-0" key={name}>
  83. <div className="card-body px-5 py-4 mt-3">
  84. <div className="row mb-3">
  85. <div className="col-9">
  86. <h2 className="card-title h3 border-bottom pb-2 mb-3">
  87. <Link href={`${url}`}>{name}</Link>
  88. </h2>
  89. <p className="card-text text-muted">{description}</p>
  90. </div>
  91. <div className='col-3'>
  92. <div>
  93. <PluginCardButton />
  94. </div>
  95. <div className="mt-4">
  96. <PluginDeleteButton />
  97. </div>
  98. </div>
  99. </div>
  100. <div className="row">
  101. <div className="col-12 d-flex flex-wrap gap-2">
  102. {/* {topics?.map((topic: string) => {
  103. return (
  104. <span key={`${name}-${topic}`} className="badge rounded-1 mp-bg-light-blue text-dark fw-normal">
  105. {topic}
  106. </span>
  107. );
  108. })} */}
  109. </div>
  110. </div>
  111. </div>
  112. <div className="card-footer px-5 border-top-0 mp-bg-light-blue">
  113. <p className="d-flex justify-content-between align-self-center mb-0">
  114. <span>
  115. {/* {owner.login === 'weseek' ? <FontAwesomeIcon icon={faCircleCheck} className="me-1 text-primary" /> : <></>}
  116. <a href={owner.html_url} target="_blank" rel="noreferrer">
  117. {owner.login}
  118. </a> */}
  119. </span>
  120. {/* <span>
  121. <FontAwesomeIcon icon={faCircleArrowDown} className="me-1" /> {stargazersCount}
  122. </span> */}
  123. </p>
  124. </div>
  125. </div>
  126. );
  127. };