Skip to content

Commit 85cd496

Browse files
author
Ajit Kumar
committed
feat(plugin): add PluginStatus component for managing plugin status display and updates
1 parent bac674b commit 85cd496

5 files changed

Lines changed: 92 additions & 55 deletions

File tree

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"gapis",
4141
"hangingpiece",
4242
"hideloading",
43+
"hilightjs",
4344
"hintrc",
4445
"hljs",
4546
"iconsrc",

client/components/pluginStatus.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { capitalize, getLoggedInUser, hideLoading, showLoading } from 'lib/helpers';
2+
import select from './dialogs/select';
3+
4+
/**
5+
*
6+
* @param {object} props
7+
* @param {string} props.status
8+
* @param {string} props.id
9+
* @param {'default'|'button'} [props.style]
10+
* @returns
11+
*/
12+
export default async function PluginStatus({ status, id, style = 'default' }) {
13+
if (!status) return null;
14+
const { isAdmin } = (await getLoggedInUser()) || {};
15+
16+
if (style === 'button') {
17+
return (
18+
<button
19+
type='button'
20+
data-id={id}
21+
onclick={isAdmin ? changePluginStatus : undefined}
22+
title='Plugin status'
23+
className={`status-button ${status}`}
24+
>
25+
{capitalize(status)}
26+
</button>
27+
);
28+
}
29+
30+
return (
31+
<span data-id={id} onclick={isAdmin ? changePluginStatus : undefined} title='Plugin status' className={`status-indicator ${status}`}>
32+
{status}
33+
</span>
34+
);
35+
}
36+
37+
/**
38+
*
39+
* @param {MouseEvent} e
40+
* @returns
41+
*/
42+
async function changePluginStatus(e) {
43+
e.preventDefault();
44+
e.stopPropagation();
45+
try {
46+
const { target } = e;
47+
const { id } = target.dataset;
48+
const status = await select('Change plugin status', ['approve', 'reject']);
49+
if (!status) return;
50+
51+
let reason;
52+
if (status === 'reject') {
53+
reason = await prompt('Reason', { type: 'textarea' });
54+
}
55+
showLoading();
56+
const res = await fetch('/api/plugin', {
57+
method: 'PATCH',
58+
headers: {
59+
'Content-Type': 'application/json',
60+
},
61+
body: JSON.stringify({ status, id, reason }),
62+
});
63+
const data = await res.json();
64+
if (data.error) {
65+
alert('Error', data.error);
66+
return;
67+
}
68+
69+
const pluginRes = await fetch(`/api/plugin/${id}`);
70+
const pluginData = await pluginRes.json();
71+
target.textContent = capitalize(pluginData.status);
72+
target.className = pluginData.status;
73+
} catch (error) {
74+
alert('Error', error.message);
75+
} finally {
76+
hideLoading();
77+
}
78+
}

client/components/plugins/index.js

Lines changed: 3 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import './style.scss';
22
import AdSense from 'components/adsense';
33
import alert from 'components/dialogs/alert';
44
import confirm from 'components/dialogs/confirm';
5-
import prompt from 'components/dialogs/prompt';
65
import select from 'components/dialogs/select';
7-
import { calcRating, capitalize, getLoggedInUser, hideLoading, showLoading, since } from 'lib/helpers';
6+
import PluginStatus from 'components/pluginStatus';
7+
import { calcRating, getLoggedInUser, hideLoading, showLoading, since } from 'lib/helpers';
88
import Router from 'lib/Router';
99

1010
export default function Plugins({ user, orderBy, status, name }) {
@@ -75,11 +75,7 @@ function Plugin({
7575
<div title='Downloads counter'>
7676
{downloads.toLocaleString()} <span className='icon download' />
7777
</div>
78-
{Boolean(status) && (
79-
<span data-id={id} onclick={isAdmin ? changePluginStatus : undefined} title='Plugin status' className={`status-indicator ${status}`}>
80-
{status}
81-
</span>
82-
)}
78+
<PluginStatus status={status} id={id} />
8379
<div>{calcRating(upVotes, downVotes)}</div>
8480
{comments > 0 && (
8581
<div>
@@ -154,49 +150,6 @@ async function deletePlugin(e, id) {
154150
}
155151
}
156152

157-
/**
158-
*
159-
* @param {MouseEvent} e
160-
* @returns
161-
*/
162-
async function changePluginStatus(e) {
163-
e.preventDefault();
164-
e.stopPropagation();
165-
try {
166-
const { target } = e;
167-
const { id } = target.dataset;
168-
const status = await select('Change plugin status', ['approve', 'reject']);
169-
if (!status) return;
170-
171-
let reason;
172-
if (status === 'reject') {
173-
reason = await prompt('Reason', { type: 'textarea' });
174-
}
175-
showLoading();
176-
const res = await fetch('/api/plugin', {
177-
method: 'PATCH',
178-
headers: {
179-
'Content-Type': 'application/json',
180-
},
181-
body: JSON.stringify({ status, id, reason }),
182-
});
183-
const data = await res.json();
184-
if (data.error) {
185-
alert('Error', data.error);
186-
return;
187-
}
188-
189-
const pluginRes = await fetch(`/api/plugin/${id}`);
190-
const pluginData = await pluginRes.json();
191-
target.textContent = capitalize(pluginData.status);
192-
target.className = pluginData.status;
193-
} catch (error) {
194-
alert('Error', error.message);
195-
} finally {
196-
hideLoading();
197-
}
198-
}
199-
200153
function Actions({ user, pluginsUser, id, isAdmin }) {
201154
const $el = <small className='icon-buttons' />;
202155
const $delete = <span title='delete plugin' className='link icon delete danger' onclick={(e) => deletePlugin(e, id)} />;

client/pages/plugin/index.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import confirm from 'components/dialogs/confirm';
77
import prompt from 'components/dialogs/prompt';
88
import Input from 'components/input';
99
import MonthSelect from 'components/MonthSelect';
10+
import PluginStatus from 'components/pluginStatus';
1011
import YearSelect from 'components/YearSelect';
1112
import hilightjs from 'highlight.js';
1213
import Ref from 'html-tag-js/ref';
@@ -25,6 +26,7 @@ export default async function Plugin({ id: pluginId, section = 'description' })
2526
id,
2627
name,
2728
price,
29+
status,
2830
author,
2931
version,
3032
license,
@@ -97,6 +99,7 @@ export default async function Plugin({ id: pluginId, section = 'description' })
9799
<span className='icon download' /> Install
98100
</button>
99101
)}
102+
<PluginStatus status={status} id={id} style='button' />
100103
</div>
101104
<div className='info-container'>
102105
<div className='info'>
@@ -392,8 +395,9 @@ function CommentsContainerAndForm({ plugin, listRef, user, id, userComment }) {
392395
);
393396
}
394397

395-
const { comment, vote, id: commentId } = userComment;
398+
const { comment, vote } = userComment;
396399
const form = Ref();
400+
let commentId = userComment.id;
397401

398402
return (
399403
<div className='comments'>
@@ -428,11 +432,12 @@ function CommentsContainerAndForm({ plugin, listRef, user, id, userComment }) {
428432

429433
let $comment;
430434

435+
commentId = commentId || res.id;
431436
if (commentId) {
432437
userComment = await fetch(`/api/comment/${commentId}`).then((userRes) => userRes.json());
433438
$comment = tag.get(`#comment_${commentId}`);
434439
} else {
435-
userComment = await getUserComment(id);
440+
userComment = await getUserComment(commentId);
436441
}
437442

438443
if (!userComment?.comment) {

server/apis/comment.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ router.post('/', async (req, res) => {
126126

127127
if (updates.length) {
128128
await Comment.update(updates, [Comment.ID, alreadyVoted.id]);
129-
res.send({ message: 'Comment updated' });
129+
res.send({ message: 'Comment updated', id: alreadyVoted.id, comment, vote });
130130
if (isVoteChanged) {
131131
updateVoteInPlugin(vote, pluginId);
132132
}
@@ -136,7 +136,7 @@ router.post('/', async (req, res) => {
136136
return;
137137
}
138138

139-
res.send({ message: 'Comment unchanged' });
139+
res.send({ message: 'Comment unchanged', id: alreadyVoted.id, comment: alreadyVoted.comment, vote: alreadyVoted.vote });
140140
return;
141141
}
142142

@@ -150,7 +150,7 @@ router.post('/', async (req, res) => {
150150
if (vote !== Comment.VOTE_NULL) {
151151
updateVoteInPlugin(vote, pluginId);
152152
}
153-
res.send({ message: 'Comment added', comment: row });
153+
res.send({ message: 'Comment added', id: row.id, comment, vote });
154154
voteMessage = vote !== Comment.VOTE_NULL ? `${loggedInUser.name} voted ${Comment.getVoteString(vote)}` : '';
155155
commentMessage = comment ? `${loggedInUser.name} commented: ${comment}` : '';
156156
sendEmail(plugin.author_email, plugin.author, `New review for your Acode plugin - ${plugin.name}.`, getNotificationMessage());

0 commit comments

Comments
 (0)