Skip to content

Commit

Permalink
Merge pull request #83 from rairprotocol/80-categories
Browse files Browse the repository at this point in the history
Category config and login message
  • Loading branch information
sarora180673 authored Jul 3, 2024
2 parents edcee4b + 2368e7d commit fe760c1
Show file tree
Hide file tree
Showing 10 changed files with 258 additions and 11 deletions.
126 changes: 126 additions & 0 deletions rair-front/src/components/adminViews/ServerSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,16 @@ import { OptionsType } from '../common/commonTypes/InputSelectTypes.types';
import InputField from '../common/InputField';
import InputSelect from '../common/InputSelect';

type Category = {
name: string;
_id?: string;
files?: number;
};

const ServerSettings = ({ fullContractData }) => {
const serverSettings = useServerSettings();
const [productOptions, setProductOptions] = useState<OptionsType[]>();
const [categoryList, setCategoryList] = useState<Category[]>([]);

const [customLightModeLogo, setCustomLightModeLogo] = useState({ name: '' });
const [customDarkModeLogo, setCustomDarkModeLogo] = useState({ name: '' });
Expand Down Expand Up @@ -60,6 +67,17 @@ const ServerSettings = ({ fullContractData }) => {
serverSettings.setFooterLinks(aux);
};

const getCategories = useCallback(async () => {
const { success, result } = await rFetch('/api/categories');
if (success) {
setCategoryList(result);
}
}, []);

useEffect(() => {
getCategories();
}, [getCategories]);

const setServerSetting = useCallback(
async (setting) => {
const { success } = await rFetch(`/api/settings/`, {
Expand Down Expand Up @@ -144,6 +162,27 @@ const ServerSettings = ({ fullContractData }) => {
serverSettings.getServerSettings();
}, [serverSettings.getServerSettings]);

const deleteCategory = useCallback(
(index) => {
const aux = [...categoryList];
aux.splice(index, 1);
setCategoryList(aux);
},
[categoryList]
);

const updateCategory = useCallback(
(index) => (value) => {
const aux = [...categoryList];
aux[index] = {
...aux[index],
name: value
};
setCategoryList(aux);
},
[categoryList]
);

useEffect(() => {
serverSettings.setFeaturedProduct('null');
if (serverSettings.featuredContract === 'null') {
Expand Down Expand Up @@ -578,6 +617,73 @@ const ServerSettings = ({ fullContractData }) => {
);
})}
</div>
<div className="col-12 px-5 my-2">
<h3>Categories</h3>
{categoryList.map((categoryData, index) => {
return (
<div key={index} className="row">
<div className="col-12 col-md-10">
<InputField
customClass="rounded-rair form-control"
getter={categoryData.name}
setter={updateCategory(index)}
type="text"
/>
</div>
<button
disabled={!!categoryData.files}
onClick={() => deleteCategory(index)}
className="col-12 col-md-2 btn btn-danger">
{categoryData.files ? (
<>
{categoryData.files}{' '}
<small>files using this category</small>
</>
) : (
<i className="fa-trash fas" />
)}
</button>
</div>
);
})}
<button
className="float-start btn"
style={{
color: textColor,
background: primaryButtonColor
}}
onClick={async () => {
const result = await rFetch('/api/categories', {
method: 'POST',
body: JSON.stringify({
list: categoryList.map((item) => ({
_id: item._id,
name: item.name
}))
}),
headers: {
'Content-Type': 'application/json'
}
});
if (result.success) {
reactSwal.fire('Success', 'Categories updated', 'success');
getCategories();
}
}}>
Set
</button>
<button
className="btn btn-success float-end"
onClick={() => {
const aux = categoryList ? [...categoryList] : [];
aux.push({
name: ''
});
setCategoryList(aux);
}}>
Add
</button>
</div>
<div className="col-12 px-5 my-2">
<h3>Footer items</h3>
{serverSettings.footerLinks &&
Expand Down Expand Up @@ -657,6 +763,26 @@ const ServerSettings = ({ fullContractData }) => {
Set
</button>
</div>
<div className="col-12 px-5 my-2">
<h3>Default Signup Message</h3>
<InputField
customClass="rounded-rair form-control"
getter={serverSettings.signupMessage}
setter={serverSettings.setSignupMessage}
placeholder="Message sent through notifications"
/>
<button
className="btn rair-button"
style={{
background: secondaryButtonColor,
color: textColor
}}
onClick={() =>
setServerSetting({ signupMessage: serverSettings.signupMessage })
}>
Set
</button>
</div>
</div>
</div>
);
Expand Down
4 changes: 4 additions & 0 deletions rair-front/src/components/adminViews/useServerSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const useServerSettings = () => {
import.meta.env.VITE_NODE_ADDRESS
);
const [legal, setLegal] = useState('');
const [signupMessage, setSignupMessage] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [featuredContract, setFeaturedContract] = useState('null');
const [featuredProduct, setFeaturedProduct] = useState('null');
Expand Down Expand Up @@ -47,6 +48,7 @@ const useServerSettings = () => {
settings?.nodeAddress || import.meta.env.VITE_NODE_ADDRESS
);
setLegal(settings?.legal || '');
setSignupMessage(settings?.signupMessage || '');
if (settings.featuredCollection) {
setFeaturedContract(settings?.featuredCollection?.contract?._id);
setFeaturedProduct(settings?.featuredCollection?._id);
Expand Down Expand Up @@ -171,6 +173,8 @@ const useServerSettings = () => {
setFooterLinks,
legal,
setLegal,
signupMessage,
setSignupMessage,
blockchainSettings,
isLoading
};
Expand Down
10 changes: 9 additions & 1 deletion rair-node/bin/api/auth/auth.Service.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const { File, User, MediaViewLog, Unlock, ServerSetting } = require('../../model
const AppError = require('../../utils/errors/AppError');
const { checkBalanceAny, checkBalanceProduct, checkAdminTokenOwns } = require('../../integrations/ethers/tokenValidation');
const { superAdminInstance } = require('../../utils/vaultSuperAdmin');
const { emitEvent } = require('../../integrations/socket.io');

module.exports = {
generateChallengeMessage: async (req, res, next) => {
Expand Down Expand Up @@ -87,7 +88,14 @@ module.exports = {
}

userData.adminRights = await checkAdminTokenOwns(userData.publicAddress);
const { superAdmins, superAdminsOnVault } = await ServerSetting.findOne({});
const { superAdmins, superAdminsOnVault, signupMessage } = await ServerSetting.findOne({});
const socket = req.app.get('socket');
emitEvent(socket)(
userData.publicAddress,
'message',
signupMessage,
[],
);
userData.superAdmin = superAdminsOnVault
? await superAdminInstance.hasSuperAdminRights(userData.publicAddress)
: superAdmins.includes(userData.publicAddress);
Expand Down
26 changes: 26 additions & 0 deletions rair-node/bin/api/categories/categories.Controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const { Router } = require('express');
const {
updateCategories,
getCategories,
} = require('./categories.Service');
const { requireUserSession } = require('../../middleware/verifyUserSession');
const validation = require('../../middleware/validation');
const { verifySuperAdmin } = require('../../middleware');

const router = Router();

router.get(
'/',
getCategories,
);

router.post(
'/',
validation(['dbCategory'], 'body'),
requireUserSession,
verifySuperAdmin,
updateCategories,
getCategories,
);

module.exports = router;
63 changes: 63 additions & 0 deletions rair-node/bin/api/categories/categories.Service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const { Category, File } = require('../../models');
const AppError = require('../../utils/errors/AppError');

module.exports = {
getCategories: async (req, res, next) => {
try {
const list = await Category.aggregate([{
$lookup: {
from: 'File',
localField: '_id',
foreignField: 'category',
as: 'files',
},
}, {
$project: {
_id: 1,
name: 1,
files: {
$size: '$files',
},
},
}]);
return res.json({ result: list, success: true });
} catch (error) {
return next(new AppError(error));
}
},
updateCategories: async (req, res, next) => {
try {
const currentList = await Category.find().lean();
const { list } = req.body;
// eslint-disable-next-line no-restricted-syntax
for await (const category of currentList) {
const update = list.find((item) => item?._id === category._id.toString());
if (update) {
await Category.findByIdAndUpdate(update._id, { $set: { name: update.name } });
} else {
const usingCategory = await File.findOne({
category: category._id,
});
if (!usingCategory) {
await Category.findByIdAndDelete(category._id);
}
}
}
// eslint-disable-next-line no-restricted-syntax
for await (const category of list) {
if (category._id) {
// eslint-disable-next-line no-continue
continue;
} else {
const newCat = new Category({
name: category.name,
});
await newCat.save();
}
}
return next();
} catch (error) {
return next(new AppError(error));
}
},
};
11 changes: 9 additions & 2 deletions rair-node/bin/integrations/ethers/importContractData.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,15 @@ module.exports = {
limit,
],
);
const ownerResponse = await alchemySDK.nft.getOwnersForNft(nft.contract.address, nft.tokenId);
[nft.owner] = ownerResponse.owners;
try {
const ownerResponse = await alchemySDK.nft.getOwnersForNft(
nft.contract.address,
nft.tokenId,
);
[nft.owner] = ownerResponse.owners;
} catch (err) {
log.error(`Could not query owner of NFT #${nft.tokenId}`);
}
if (insertToken(nft, contract._id)) {
numberOfTokensAdded += 1;
}
Expand Down
1 change: 1 addition & 0 deletions rair-node/bin/models/serverSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const ServerSetting = new Schema({
legal: { type: String, required: false },
// Favicon
favicon: { type: String, required: false },
signupMessage: { type: String, required: false, default: 'Welcome' },
}, { versionKey: false, timestamps: false });

module.exports = ServerSetting;
2 changes: 2 additions & 0 deletions rair-node/bin/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const nftController = require('../api/nft/nft.Controller');
const uploadController = require('../api/upload/upload.Controller');
const favoritesController = require('../api/favorites/favorites.Controller');
const notificationsController = require('../api/notifications/notifications.Controller');
const categoriesController = require('../api/categories/categories.Controller');

const router = Router();
router.use('/analytics', analyticsController);
Expand All @@ -36,6 +37,7 @@ router.use('/settings', settingsRouter);
router.use('/tokens', tokensController);
router.use('/upload', uploadController);
router.use('/notifications', notificationsController);
router.use('/categories', categoriesController);

// Custom temporary endpoint for the monaco2021
router.use('/', require('./monaco2021'));
Expand Down
7 changes: 7 additions & 0 deletions rair-node/bin/schemas/databaseSchemas.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ module.exports = {
url: Joi.string(),
})),
legal: Joi.string(),
signupMessage: Joi.string(),
}),
dbContracts: () => ({
title: Joi.string(),
Expand Down Expand Up @@ -123,4 +124,10 @@ module.exports = {
type: Joi.string(),
read: Joi.boolean(),
}),
dbCategory: () => ({
list: Joi.array().items(Joi.object({
name: Joi.string().required(),
_id: mongoId,
})),
}),
};
19 changes: 11 additions & 8 deletions rair-node/bin/seeds/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,21 @@ const { Blockchain, Category, ServerSetting, Contract } = require('../models');

module.exports = async () => {
try {
// eslint-disable-next-line no-restricted-syntax
for await (const category of categories) {
await Category.findOneAndUpdate(
category,
category,
{ upsert: true, new: true },
);
const count = await Category.estimatedDocumentCount();
if (count === 0) {
// eslint-disable-next-line no-restricted-syntax
for await (const category of categories) {
await Category.findOneAndUpdate(
category,
category,
{ upsert: true, new: true },
);
}
log.info('Categories empty, populating with default values.');
}
} catch (e) {
log.error(`Error seeding categories: ${e}`);
}
log.info('Categories seeded.');

try {
// eslint-disable-next-line no-restricted-syntax
Expand Down

0 comments on commit fe760c1

Please sign in to comment.