Autosave: 20260401-210827

This commit is contained in:
Flatlogic Bot 2026-04-01 21:08:28 +00:00
parent 0704729e11
commit 195e1589a3
73 changed files with 499 additions and 523 deletions

View File

@ -39,7 +39,7 @@ const config = {
},
uploadDir: os.tmpdir(),
email: {
from: 'Multi-Client Detergents POS <app@flatlogic.app>',
from: 'نظام إدارة المحل ونقطة البيع <app@flatlogic.app>',
host: 'email-smtp.us-east-1.amazonaws.com',
port: 587,
auth: {

View File

@ -55,8 +55,8 @@ const options = {
openapi: "3.0.0",
info: {
version: "1.0.0",
title: "Multi-Client Detergents POS",
description: "Multi-Client Detergents POS Online REST API for Testing and Prototyping application. You can perform all major operations with your entities - create, delete and etc.",
title: "نظام إدارة المحل ونقطة البيع",
description: "واجهة API خاصة بإدارة المحل ونقطة البيع، وتوفّر عمليات الإدارة الأساسية على الكيانات والبيانات.",
},
servers: [
{

View File

@ -7,30 +7,23 @@ let publicRoleCache = null;
// Function to asynchronously fetch and cache the 'Public' role
async function fetchAndCachePublicRole() {
try {
// Use RolesDBApi to find the role by name 'Public'
publicRoleCache = await RolesDBApi.findBy({ name: 'Public' });
try {
// Use RolesDBApi to find the role by name 'Public'
publicRoleCache = await RolesDBApi.findBy({ name: 'Public' });
if (!publicRoleCache) {
console.error("WARNING: Role 'Public' not found in database during middleware startup. Check your migrations.");
// The system might not function correctly without this role. May need to throw an error or use a fallback stub.
} else {
console.log("'Public' role successfully loaded and cached.");
}
} catch (error) {
console.error("Error fetching 'Public' role during middleware startup:", error);
// Handle the error during startup fetch
throw error; // Important to know if the app can proceed without the Public role
if (!publicRoleCache) {
console.error("WARNING: لم يتم العثور على دور 'Public' في قاعدة البيانات أثناء تهيئة الصلاحيات.");
} else {
console.log("تم تحميل دور 'Public' وحفظه في الذاكرة المؤقتة بنجاح.");
}
} catch (error) {
console.error("حدث خطأ أثناء تحميل دور 'Public' عند بدء تشغيل وسيط الصلاحيات:", error);
throw error;
}
}
// Trigger the role fetching when the check-permissions.js module is imported/loaded
// This should happen during application startup when routes are being configured.
fetchAndCachePublicRole().catch(error => {
// Handle the case where the fetchAndCachePublicRole promise is rejected
console.error("Critical error during permissions middleware initialization:", error);
// Decide here if the process should exit if the Public role is essential.
// process.exit(1);
fetchAndCachePublicRole().catch((error) => {
console.error('خطأ حرج أثناء تهيئة وسيط الصلاحيات:', error);
});
/**
@ -39,85 +32,63 @@ fetchAndCachePublicRole().catch(error => {
* @return {import("express").RequestHandler} Express middleware function.
*/
function checkPermissions(permission) {
return async (req, res, next) => {
const { currentUser } = req;
return async (req, res, next) => {
const { currentUser } = req;
// 1. Check self-access bypass (only if the user is authenticated)
if (currentUser && (currentUser.id === req.params.id || currentUser.id === req.body.id)) {
return next(); // User has access to their own resource
if (currentUser && (currentUser.id === req.params.id || currentUser.id === req.body.id)) {
return next();
}
if (currentUser) {
const customPermissions = Array.isArray(currentUser.custom_permissions)
? currentUser.custom_permissions
: [];
const userPermission = customPermissions.find(
(cp) => cp.name === permission,
);
if (userPermission) {
return next();
}
}
let effectiveRole = null;
try {
if (currentUser && currentUser.app_role) {
effectiveRole = currentUser.app_role;
} else if (!publicRoleCache) {
console.error("ذاكرة دور 'Public' فارغة. سيتم إعادة تحميله مباشرةً من قاعدة البيانات.");
effectiveRole = await RolesDBApi.findBy({ name: 'Public' });
if (!effectiveRole) {
return next(new Error('خطأ داخلي: تعذر تحميل دور الوصول العام.'));
}
} else {
effectiveRole = publicRoleCache;
}
// 2. Check Custom Permissions (only if the user is authenticated)
if (currentUser) {
// Ensure custom_permissions is an array before using find
const customPermissions = Array.isArray(currentUser.custom_permissions)
? currentUser.custom_permissions
: [];
const userPermission = customPermissions.find(
(cp) => cp.name === permission,
);
if (userPermission) {
return next(); // User has a custom permission
}
}
if (!effectiveRole) {
return next(new Error('خطأ داخلي: تعذر تحديد الدور الفعّال للتحقق من الصلاحية.'));
}
// 3. Determine the "effective" role for permission check
let effectiveRole = null;
try {
if (currentUser && currentUser.app_role) {
// User is authenticated and has an assigned role
effectiveRole = currentUser.app_role;
} else {
// User is NOT authenticated OR is authenticated but has no role
// Use the cached 'Public' role
if (!publicRoleCache) {
// If the cache is unexpectedly empty (e.g., startup error caught),
// we can try fetching the role again synchronously (less ideal) or just deny access.
console.error("Public role cache is empty. Attempting synchronous fetch...");
// Less efficient fallback option:
effectiveRole = await RolesDBApi.findBy({ name: 'Public' }); // Could be slow
if (!effectiveRole) {
// If even the synchronous attempt failed
return next(new Error("Internal Server Error: Public role missing and cannot be fetched."));
}
} else {
effectiveRole = publicRoleCache; // Use the cached object
}
}
let rolePermissions = [];
if (typeof effectiveRole.getPermissions === 'function') {
rolePermissions = await effectiveRole.getPermissions();
} else if (Array.isArray(effectiveRole.permissions)) {
rolePermissions = effectiveRole.permissions;
} else {
console.error('تنسيق كائن الدور غير صالح ولا يحتوي على الصلاحيات المطلوبة:', effectiveRole);
return next(new Error('خطأ داخلي: بيانات الدور غير صالحة للتحقق من الصلاحيات.'));
}
// Check if we got a valid role object
if (!effectiveRole) {
return next(new Error("Internal Server Error: Could not determine effective role."));
}
// 4. Check Permissions on the "effective" role
// Assume the effectiveRole object (from app_role or RolesDBApi) has a getPermissions() method
// or a 'permissions' property (if permissions are eagerly loaded).
let rolePermissions = [];
if (typeof effectiveRole.getPermissions === 'function') {
rolePermissions = await effectiveRole.getPermissions(); // Get permissions asynchronously if the method exists
} else if (Array.isArray(effectiveRole.permissions)) {
rolePermissions = effectiveRole.permissions; // Or take from property if permissions are pre-loaded
} else {
console.error("Role object lacks getPermissions() method or permissions property:", effectiveRole);
return next(new Error("Internal Server Error: Invalid role object format."));
}
if (rolePermissions.find((p) => p.name === permission)) {
next(); // The "effective" role has the required permission
} else {
// The "effective" role does not have the required permission
const roleName = effectiveRole.name || 'unknown role';
next(new ValidationError('auth.forbidden', `Role '${roleName}' denied access to '${permission}'.`));
}
} catch (e) {
// Handle errors during role or permission fetching
console.error("Error during permission check:", e);
next(e); // Pass the error to the next middleware
}
};
if (rolePermissions.find((p) => p.name === permission)) {
next();
} else {
next(new ValidationError('auth.forbidden', `Role '${effectiveRole.name || 'unknown'}' denied '${permission}'.`));
}
} catch (error) {
console.error('حدث خطأ أثناء التحقق من الصلاحيات:', error);
next(error);
}
};
}
const METHOD_MAP = {
@ -134,16 +105,13 @@ const METHOD_MAP = {
* @return {import("express").RequestHandler} Express middleware function.
*/
function checkCrudPermissions(name) {
return (req, res, next) => {
// Dynamically determine the permission name (e.g., 'READ_USERS')
const permissionName = `${METHOD_MAP[req.method]}_${name.toUpperCase()}`;
// Call the checkPermissions middleware with the determined permission
checkPermissions(permissionName)(req, res, next);
};
return (req, res, next) => {
const permissionName = `${METHOD_MAP[req.method]}_${name.toUpperCase()}`;
checkPermissions(permissionName)(req, res, next);
};
}
module.exports = {
checkPermissions,
checkCrudPermissions,
checkPermissions,
checkCrudPermissions,
};

View File

@ -13,8 +13,8 @@ const loadRolesModules = () => {
RolesDBApi: require('../db/api/roles'),
};
} catch (error) {
console.error('Roles modules are missing. Advanced roles are required for this endpoint.', error);
const err = new Error('Roles modules are missing. Advanced roles are required for this endpoint.');
console.error('تعذر تحميل وحدات الأدوار المطلوبة لهذا المسار.', error);
const err = new Error('تعذر تحميل وحدات الأدوار المطلوبة لهذا المسار.');
err.originalError = error;
throw err;
}
@ -310,7 +310,7 @@ router.post(
if (!prompt) {
return res.status(400).send({
success: false,
error: 'Prompt is required',
error: 'النص المطلوب للذكاء الاصطناعي فارغ',
});
}

View File

@ -19,7 +19,7 @@ router.get('/image', async (req, res) => {
const data = await response.json();
res.status(200).json(data.photos[0]);
} catch (error) {
res.status(200).json({ error: 'Failed to fetch image' });
res.status(200).json({ error: 'تعذر جلب الصورة' });
}
});
@ -37,7 +37,7 @@ router.get('/video', async (req, res) => {
const data = await response.json();
res.status(200).json(data.videos[0]);
} catch (error) {
res.status(200).json({ error: 'Failed to fetch video' });
res.status(200).json({ error: 'تعذر جلب الفيديو' });
}
});

View File

@ -41,15 +41,15 @@ router.post('/', async (req, res) => {
const globalAccess = req.currentUser.app_role.globalAccess;
if (!searchQuery) {
return res.status(400).json({ error: 'Please enter a search query' });
return res.status(400).json({ error: 'يرجى إدخال عبارة للبحث' });
}
try {
const foundMatches = await SearchService.search(searchQuery, req.currentUser , organizationId, globalAccess,);
res.json(foundMatches);
} catch (error) {
console.error('Internal Server Error', error);
res.status(500).json({ error: 'Internal Server Error' });
console.error('حدث خطأ داخلي في البحث', error);
res.status(500).json({ error: 'حدث خطأ داخلي أثناء تنفيذ البحث' });
}
});

View File

@ -38,16 +38,16 @@ router.post(
wrapAsync(async (req, res) => {
const { sql } = req.body;
if (typeof sql !== 'string' || !sql.trim()) {
return res.status(400).json({ error: 'SQL is required' });
return res.status(400).json({ error: 'يرجى إدخال استعلام SQL' });
}
const normalized = sql.trim().replace(/;+\s*$/, '');
if (!/^select\b/i.test(normalized)) {
return res.status(400).json({ error: 'Only SELECT statements are allowed' });
return res.status(400).json({ error: 'يسمح فقط باستعلامات SELECT' });
}
if (normalized.includes(';')) {
return res.status(400).json({ error: 'Only a single SELECT statement is allowed' });
return res.status(400).json({ error: 'يسمح باستعلام SELECT واحد فقط في كل طلب' });
}
const rows = await db.sequelize.query(normalized, {

View File

@ -2,7 +2,7 @@ const formidable = require('formidable');
const fs = require('fs');
const config = require('../config');
const path = require('path');
const { format } = require("util");
const { format } = require('util');
const ensureDirectoryExistence = (filePath) => {
const dirname = path.dirname(filePath);
@ -13,7 +13,7 @@ const ensureDirectoryExistence = (filePath) => {
ensureDirectoryExistence(dirname);
fs.mkdirSync(dirname);
}
};
const uploadLocal = (
folder,
@ -29,9 +29,7 @@ const uploadLocal = (
return;
}
if (
validations.entity
) {
if (validations.entity) {
res.sendStatus(403);
return;
}
@ -63,7 +61,7 @@ const uploadLocal = (
if (!filename) {
fs.unlinkSync(fileTempUrl);
res.sendStatus(500);
res.status(500).send({ message: 'تعذر تحديد اسم الملف المطلوب رفعه' });
return;
}
@ -80,59 +78,57 @@ const uploadLocal = (
form.on('error', function (err) {
res.status(500).send(err);
});
}
}
};
};
const downloadLocal = async (req, res) => {
const privateUrl = req.query.privateUrl;
if (!privateUrl) {
return res.sendStatus(404);
}
res.download(path.join(config.uploadDir, privateUrl));
}
const privateUrl = req.query.privateUrl;
if (!privateUrl) {
return res.sendStatus(404);
}
res.download(path.join(config.uploadDir, privateUrl));
};
const initGCloud = () => {
const processFile = require("../middlewares/upload");
const { Storage } = require("@google-cloud/storage");
const processFile = require('../middlewares/upload');
const { Storage } = require('@google-cloud/storage');
const crypto = require('crypto')
const hash = config.gcloud.hash
const privateKey = process.env.GC_PRIVATE_KEY.replace(/\\\n/g, "\n");
const hash = config.gcloud.hash;
const privateKey = process.env.GC_PRIVATE_KEY.replace(/\\\n/g, '\n');
const storage = new Storage({
projectId: process.env.GC_PROJECT_ID,
credentials: {
client_email: process.env.GC_CLIENT_EMAIL,
private_key: privateKey
}
projectId: process.env.GC_PROJECT_ID,
credentials: {
client_email: process.env.GC_CLIENT_EMAIL,
private_key: privateKey,
},
});
const bucket = storage.bucket(config.gcloud.bucket);
return {hash, bucket, processFile};
}
return { hash, bucket, processFile };
};
const uploadGCloud = async (folder, req, res) => {
try {
const {hash, bucket, processFile} = initGCloud();
const { hash, bucket, processFile } = initGCloud();
await processFile(req, res);
let buffer = await req.file.buffer;
let filename = await req.body.filename;
if (!req.file) {
return res.status(400).send({ message: "Please upload a file!" });
return res.status(400).send({ message: 'يرجى اختيار ملف للرفع' });
}
let path = `${hash}/${folder}/${filename}`;
let blob = bucket.file(path);
const buffer = req.file.buffer;
const filename = req.body.filename;
const filePath = `${hash}/${folder}/${filename}`;
const blob = bucket.file(filePath);
console.log(path);
console.log(filePath);
const blobStream = blob.createWriteStream({
resumable: false,
});
blobStream.on("error", (err) => {
blobStream.on('error', (err) => {
console.log('Upload error');
console.log(err.message);
res.status(500).send({ message: err.message });
@ -140,58 +136,58 @@ const uploadGCloud = async (folder, req, res) => {
console.log(`https://storage.googleapis.com/${bucket.name}/${blob.name}`);
blobStream.on("finish", async (data) => {
blobStream.on('finish', async () => {
const publicUrl = format(
`https://storage.googleapis.com/${bucket.name}/${blob.name}`
`https://storage.googleapis.com/${bucket.name}/${blob.name}`,
);
res.status(200).send({
message: "Uploaded the file successfully: " + path,
message: `تم رفع الملف بنجاح: ${filePath}`,
url: publicUrl,
});
});
blobStream.end(buffer)
blobStream.end(buffer);
} catch (err) {
console.log(err);
res.status(500).send({
message: `Could not upload the file. ${err}`
message: `تعذر رفع الملف. ${err}`,
});
}
}
};
const downloadGCloud = async (req, res) => {
try {
const {hash, bucket, processFile} = initGCloud();
const { hash, bucket } = initGCloud();
const privateUrl = await req.query.privateUrl;
const privateUrl = req.query.privateUrl;
const filePath = `${hash}/${privateUrl}`;
const file = bucket.file(filePath)
const file = bucket.file(filePath);
const fileExists = await file.exists();
if (fileExists[0]) {
const stream = file.createReadStream();
stream.pipe(res);
return;
}
else {
res.status(404).send({
message: "Could not download the file. " + err,
});
}
res.status(404).send({
message: 'تعذر العثور على الملف المطلوب تنزيله',
});
} catch (err) {
res.status(404).send({
message: "Could not download the file. " + err,
message: 'تعذر تنزيل الملف.',
});
}
}
};
const deleteGCloud = async (privateUrl) => {
try {
const {hash, bucket, processFile} = initGCloud();
const { hash, bucket } = initGCloud();
const filePath = `${hash}/${privateUrl}`;
const file = bucket.file(filePath)
const file = bucket.file(filePath);
const fileExists = await file.exists();
if (fileExists[0]) {
@ -200,7 +196,7 @@ const deleteGCloud = async (privateUrl) => {
} catch (err) {
console.log(`Cannot find the file ${privateUrl}`);
}
}
};
module.exports = {
initGCloud,
@ -208,6 +204,5 @@ module.exports = {
downloadLocal,
deleteGCloud,
uploadGCloud,
downloadGCloud
}
downloadGCloud,
};

View File

@ -1,101 +1,96 @@
const errors = {
app: {
title: 'Multi-Client Detergents POS',
title: 'نظام إدارة المحل ونقطة البيع',
},
auth: {
userDisabled: 'Your account is disabled',
forbidden: 'Forbidden',
unauthorized: 'Unauthorized',
userNotFound: `Sorry, we don't recognize your credentials`,
wrongPassword: `Sorry, we don't recognize your credentials`,
weakPassword: 'This password is too weak',
emailAlreadyInUse: 'Email is already in use',
invalidEmail: 'Please provide a valid email',
userDisabled: 'تم تعطيل هذا الحساب',
forbidden: 'ليس لديك صلاحية لتنفيذ هذا الإجراء',
unauthorized: 'يجب تسجيل الدخول أولاً',
userNotFound: 'البريد الإلكتروني أو كلمة المرور غير صحيحة',
wrongPassword: 'البريد الإلكتروني أو كلمة المرور غير صحيحة',
weakPassword: 'كلمة المرور ضعيفة جدًا',
emailAlreadyInUse: 'هذا البريد الإلكتروني مستخدم بالفعل',
invalidEmail: 'يرجى إدخال بريد إلكتروني صحيح',
passwordReset: {
invalidToken:
'Password reset link is invalid or has expired',
error: `Email not recognized`,
invalidToken: 'رابط إعادة تعيين كلمة المرور غير صالح أو منتهي الصلاحية',
error: 'هذا البريد الإلكتروني غير مسجل في النظام',
},
passwordUpdate: {
samePassword: `You can't use the same password. Please create new password`
samePassword: 'لا يمكن استخدام كلمة المرور الحالية نفسها. اختر كلمة مرور جديدة',
},
userNotVerified: `Sorry, your email has not been verified yet`,
userNotVerified: 'لم يتم تأكيد البريد الإلكتروني لهذا الحساب بعد',
emailAddressVerificationEmail: {
invalidToken:
'Email verification link is invalid or has expired',
error: `Email not recognized`,
invalidToken: 'رابط تأكيد البريد الإلكتروني غير صالح أو منتهي الصلاحية',
error: 'هذا البريد الإلكتروني غير مسجل في النظام',
},
},
iam: {
errors: {
userAlreadyExists:
'User with this email already exists',
userNotFound: 'User not found',
disablingHimself: `You can't disable yourself`,
revokingOwnPermission: `You can't revoke your own owner permission`,
deletingHimself: `You can't delete yourself`,
emailRequired: 'Email is required',
userAlreadyExists: 'يوجد مستخدم بهذا البريد الإلكتروني بالفعل',
userNotFound: 'المستخدم غير موجود',
disablingHimself: 'لا يمكنك تعطيل حسابك الحالي',
revokingOwnPermission: 'لا يمكنك إزالة صلاحية المالك من حسابك الحالي',
deletingHimself: 'لا يمكنك حذف حسابك الحالي',
emailRequired: 'البريد الإلكتروني مطلوب',
},
},
importer: {
errors: {
invalidFileEmpty: 'The file is empty',
invalidFileExcel:
'Only excel (.xlsx) files are allowed',
invalidFileUpload:
'Invalid file. Make sure you are using the last version of the template.',
importHashRequired: 'Import hash is required',
importHashExistent: 'Data has already been imported',
userEmailMissing: 'Some items in the CSV do not have an email',
invalidFileEmpty: 'الملف فارغ',
invalidFileExcel: 'يسمح فقط بملفات Excel بصيغة .xlsx',
invalidFileUpload: 'الملف غير صالح. تأكد من استخدام آخر نسخة من القالب المعتمد.',
importHashRequired: 'معرّف الاستيراد مطلوب',
importHashExistent: 'تم استيراد هذه البيانات مسبقًا',
userEmailMissing: 'بعض الصفوف في ملف CSV لا تحتوي على بريد إلكتروني',
},
},
errors: {
forbidden: {
message: 'Forbidden',
message: 'ليس لديك صلاحية للوصول',
},
validation: {
message: 'An error occurred',
message: 'حدث خطأ في التحقق من البيانات',
},
searchQueryRequired: {
message: 'Search query is required',
message: 'يرجى إدخال عبارة البحث',
},
},
emails: {
invitation: {
subject: `You've been invited to {0}`,
body: `
<p>Hello,</p>
<p>You've been invited to {0} set password for your {1} account.</p>
subject: 'تمت دعوتك إلى {0}',
body: `
<p>مرحبًا،</p>
<p>تمت دعوتك إلى {0}. يرجى تعيين كلمة المرور لحسابك في {1}.</p>
<p><a href='{2}'>{2}</a></p>
<p>Thanks,</p>
<p>Your {0} team</p>
<p>شكرًا لك،</p>
<p>فريق {0}</p>
`,
},
emailAddressVerification: {
subject: `Verify your email for {0}`,
subject: 'تأكيد البريد الإلكتروني لـ {0}',
body: `
<p>Hello,</p>
<p>Follow this link to verify your email address.</p>
<p>مرحبًا،</p>
<p>استخدم هذا الرابط لتأكيد عنوان بريدك الإلكتروني.</p>
<p><a href='{0}'>{0}</a></p>
<p>If you didn't ask to verify this address, you can ignore this email.</p>
<p>Thanks,</p>
<p>Your {1} team</p>
<p>إذا لم تطلب هذا الإجراء، يمكنك تجاهل هذه الرسالة.</p>
<p>شكرًا لك،</p>
<p>فريق {1}</p>
`,
},
passwordReset: {
subject: `Reset your password for {0}`,
subject: 'إعادة تعيين كلمة المرور لـ {0}',
body: `
<p>Hello,</p>
<p>Follow this link to reset your {0} password for your {1} account.</p>
<p>مرحبًا،</p>
<p>استخدم هذا الرابط لإعادة تعيين كلمة المرور الخاصة بك في {0} لحساب {1}.</p>
<p><a href='{2}'>{2}</a></p>
<p>If you didn't ask to reset your password, you can ignore this email.</p>
<p>Thanks,</p>
<p>Your {0} team</p>
<p>إذا لم تطلب إعادة التعيين، يمكنك تجاهل هذه الرسالة.</p>
<p>شكرًا لك،</p>
<p>فريق {0}</p>
`,
},
},

View File

@ -6,8 +6,8 @@ const loadRoleService = () => {
try {
return require('./roles');
} catch (error) {
console.error('Role service is missing. Advanced roles are required for this operation.', error);
const err = new Error('Role service is missing. Advanced roles are required for this operation.');
console.error('تعذر تحميل خدمة الأدوار المطلوبة لهذه العملية.', error);
const err = new Error('تعذر تحميل خدمة الأدوار المطلوبة لهذه العملية.');
err.originalError = error;
throw err;
}
@ -25,17 +25,17 @@ module.exports = class OpenAiService {
const { widget_id } = await response.data;
await RoleService.addRoleInfo(roleId, userId, 'widgets', widget_id);
return widget_id;
} else {
console.error('=======error=======', response.data);
return { value: null, error: response.data };
}
console.error('Widget generation failed:', response.data);
return { value: null, error: response.data };
}
static async askGpt(prompt) {
if (!prompt) {
return {
success: false,
error: 'Prompt is required'
error: 'النص المطلوب للذكاء الاصطناعي فارغ',
};
}
@ -59,7 +59,7 @@ module.exports = class OpenAiService {
console.error('AI JSON decode failed:', error);
return {
success: false,
error: 'AI response parsing failed',
error: 'تعذر قراءة رد الذكاء الاصطناعي',
details: error.message || String(error),
};
}
@ -73,7 +73,7 @@ module.exports = class OpenAiService {
console.error('AI proxy error:', response);
return {
success: false,
error: response.error || response.message || 'AI proxy error',
error: response.error || response.message || 'حدث خطأ أثناء التواصل مع خدمة الذكاء الاصطناعي',
response,
};
}

View File

@ -1,6 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference path="./build/types/routes.d.ts" />
/// <reference path="./.next/types/routes.d.ts" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.

View File

@ -63,13 +63,13 @@ const AsideMenuItem = ({ item, isDropdownList = false }: Props) => {
)
const componentClass = [
'flex cursor-pointer py-1.5 ',
'flex cursor-pointer py-1.5 font-medium transition-all duration-200 ease-out',
isDropdownList ? 'px-6 text-sm' : '',
item.color
? getButtonColor(item.color, false, true)
: `${asideMenuItemStyle}`,
isLinkActive
? `text-black ${activeLinkColor} dark:text-white dark:bg-dark-800`
? `text-black ${activeLinkColor} shadow-sm dark:text-white dark:bg-dark-800`
: '',
].join(' ');

View File

@ -56,17 +56,17 @@ export default function AsideMenuLayer({ menu, className = '', ...props }: Props
return (
<aside
id='asideMenu'
className={`${className} zzz lg:py-2 lg:pl-2 w-60 fixed flex z-40 top-0 h-screen transition-position overflow-hidden`}
className={`${className} zzz lg:py-2 lg:pl-2 w-60 fixed top-0 z-40 flex h-screen overflow-hidden transition-all duration-300 ease-out`}
>
<div
className={`flex-1 flex flex-col overflow-hidden dark:bg-dark-900 ${asideStyle} ${corners}`}
className={`flex flex-1 flex-col overflow-hidden border border-slate-200/70 shadow-sm transition-all duration-300 ease-out dark:bg-dark-900 dark:border-dark-700 ${asideStyle} ${corners}`}
>
<div
className={`flex flex-row h-14 items-center justify-between ${asideBrandStyle}`}
>
<div className="text-center flex-1 lg:text-left lg:pl-6 xl:text-center xl:pl-0">
<b className="font-black">Multi-Client Detergents POS</b>
<b className="font-black tracking-[0.01em]">Multi-Client Detergents POS</b>
{organizationName && <p>{organizationName}</p>}

View File

@ -48,10 +48,13 @@ export default function BaseButton({
'justify-center',
'items-center',
'whitespace-nowrap',
'font-semibold',
'tracking-[0.01em]',
'focus:outline-none',
'transition-colors',
'transition-all',
'duration-200',
'ease-out',
'focus:ring',
'duration-150',
'border',
disabled ? 'cursor-not-allowed' : 'cursor-pointer',
roundedFull ? 'rounded-full' : `${corners}`,
@ -60,7 +63,7 @@ export default function BaseButton({
]
if (!label && icon) {
componentClass.push('p-1')
componentClass.push('p-1.5')
} else if (small) {
componentClass.push('text-sm', roundedFull ? 'px-3 py-1' : 'p-1')
} else {
@ -69,6 +72,8 @@ export default function BaseButton({
if (disabled) {
componentClass.push(outline ? 'opacity-50' : 'opacity-70')
} else {
componentClass.push('hover:-translate-y-px', 'hover:shadow-sm', 'active:translate-y-0')
}
const componentClassString = componentClass.join(' ')

View File

@ -37,16 +37,16 @@ export default function CardBox({
const corners = useAppSelector((state) => state.style.corners);
const cardsStyle = useAppSelector((state) => state.style.cardsStyle);
const componentClass = [
`flex dark:border-dark-700 dark:bg-dark-900`,
`flex dark:border-dark-700 dark:bg-dark-900 transition-all duration-300 ease-out motion-reduce:transition-none`,
className,
corners !== 'rounded-full'? corners : 'rounded-3xl',
flex,
isList ? '' : `${cardsStyle}`,
hasTable ? '' : `border-dark-700 dark:border-dark-700`,
hasTable ? '' : `border-dark-700 dark:border-dark-700`,
]
if (isHoverable) {
componentClass.push('hover:shadow-lg transition-shadow duration-500')
componentClass.push('hover:-translate-y-0.5 hover:shadow-lg')
}
return React.createElement(

View File

@ -35,9 +35,9 @@ export default function NavBar({ menu, className = '', children }: Props) {
return (
<nav
className={`${className} top-0 inset-x-0 fixed ${bgColor} h-14 z-30 transition-position w-screen lg:w-auto dark:bg-dark-800`}
className={`${className} top-0 inset-x-0 fixed ${bgColor} h-14 z-30 w-screen transition-all duration-300 ease-out backdrop-blur-sm lg:w-auto dark:bg-dark-800`}
>
<div className={`flex lg:items-stretch ${containerMaxW} ${isScrolled && `border-b border-pavitra-400 dark:border-dark-700`}`}>
<div className={`flex lg:items-stretch ${containerMaxW} ${isScrolled ? 'border-b border-pavitra-400/70 shadow-sm shadow-slate-200/60 dark:border-dark-700 dark:shadow-none' : ''}`}>
<div className="flex flex-1 items-stretch h-14">{children}</div>
<div className="flex-none items-stretch flex h-14 lg:hidden">
<NavBarItemPlain onClick={handleMenuNavBarToggleClick}>
@ -47,7 +47,7 @@ export default function NavBar({ menu, className = '', children }: Props) {
<div
className={`${
isMenuNavBarActive ? 'block' : 'hidden'
} flex items-center max-h-screen-menu overflow-y-auto lg:overflow-visible absolute w-screen top-14 left-0 ${bgColor} shadow-lg lg:w-auto lg:flex lg:static lg:shadow-none dark:bg-dark-800`}
} absolute left-0 top-14 flex max-h-screen-menu w-screen items-center overflow-y-auto ${bgColor} shadow-lg transition-all duration-300 ease-out lg:static lg:w-auto lg:flex lg:overflow-visible lg:shadow-none dark:bg-dark-800`}
>
<NavBarMenuList menu={menu} />
</div>

View File

@ -17,7 +17,7 @@ export default function NavBarItemPlain({
const navBarItemLabelStyle = useAppSelector((state) => state.style.navBarItemLabelStyle)
const navBarItemLabelHoverStyle = useAppSelector((state) => state.style.navBarItemLabelHoverStyle)
const classBase = 'items-center cursor-pointer dark:text-white dark:hover:text-slate-400'
const classBase = 'items-center cursor-pointer font-medium transition-colors duration-200 ease-out dark:text-white dark:hover:text-slate-400'
const classAddon = `${display} ${navBarItemLabelStyle} ${navBarItemLabelHoverStyle} ${
useMargin ? 'my-2 mx-3' : 'py-2 px-3'
}`

View File

@ -93,7 +93,7 @@ const CardOrganizations = ({
))}
{!loading && organizations.length === 0 && (
<div className='col-span-full flex items-center justify-center h-40'>
<p className=''>No data to display</p>
<p className=''>لا توجد بيانات للعرض</p>
</div>
)}
</ul>

View File

@ -70,7 +70,7 @@ const ListOrganizations = ({ organizations, loading, onDelete, currentPage, numP
))}
{!loading && organizations.length === 0 && (
<div className='col-span-full flex items-center justify-center h-40'>
<p className=''>No data to display</p>
<p className=''>لا توجد بيانات للعرض</p>
</div>
)}
</div>

View File

@ -395,12 +395,12 @@ const TableSampleOrganizations = ({ filterItems, setFilterItems, filters, showGr
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">إجراء</div>
<BaseButton
className="my-2"
type='reset'
color='danger'
label='Delete'
label='حذف'
onClick={() => {
deleteFilter(filterItem.id)
}}
@ -413,13 +413,13 @@ const TableSampleOrganizations = ({ filterItems, setFilterItems, filters, showGr
<BaseButton
className="my-2 mr-3"
color="success"
label='Apply'
label='تطبيق'
onClick={handleSubmit}
/>
<BaseButton
className="my-2"
color='info'
label='Cancel'
label='إلغاء'
onClick={handleReset}
/>
</div>
@ -429,14 +429,14 @@ const TableSampleOrganizations = ({ filterItems, setFilterItems, filters, showGr
</CardBox> : null
}
<CardBoxModal
title="Please confirm"
title="تأكيد العملية"
buttonColor="info"
buttonLabel={loading ? 'Deleting...' : 'Confirm'}
buttonLabel={loading ? 'جارٍ الحذف...' : 'تأكيد'}
isActive={isModalTrashActive}
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>هل أنت متأكد من حذف هذا العنصر؟</p>
</CardBoxModal>
@ -450,7 +450,7 @@ const TableSampleOrganizations = ({ filterItems, setFilterItems, filters, showGr
<BaseButton
className='me-4'
color='danger'
label={`Delete ${selectedRows.length === 1 ? 'Row' : 'Rows'}`}
label={`حذف ${selectedRows.length === 1 ? 'السجل المحدد' : 'السجلات المحددة'}`}
onClick={() => onDeleteRows(selectedRows)}
/>,
document.getElementById('delete-rows-button'),

View File

@ -93,7 +93,7 @@ const CardPermissions = ({
))}
{!loading && permissions.length === 0 && (
<div className='col-span-full flex items-center justify-center h-40'>
<p className=''>No data to display</p>
<p className=''>لا توجد بيانات للعرض</p>
</div>
)}
</ul>

View File

@ -70,7 +70,7 @@ const ListPermissions = ({ permissions, loading, onDelete, currentPage, numPages
))}
{!loading && permissions.length === 0 && (
<div className='col-span-full flex items-center justify-center h-40'>
<p className=''>No data to display</p>
<p className=''>لا توجد بيانات للعرض</p>
</div>
)}
</div>

View File

@ -395,12 +395,12 @@ const TableSamplePermissions = ({ filterItems, setFilterItems, filters, showGrid
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">إجراء</div>
<BaseButton
className="my-2"
type='reset'
color='danger'
label='Delete'
label='حذف'
onClick={() => {
deleteFilter(filterItem.id)
}}
@ -413,13 +413,13 @@ const TableSamplePermissions = ({ filterItems, setFilterItems, filters, showGrid
<BaseButton
className="my-2 mr-3"
color="success"
label='Apply'
label='تطبيق'
onClick={handleSubmit}
/>
<BaseButton
className="my-2"
color='info'
label='Cancel'
label='إلغاء'
onClick={handleReset}
/>
</div>
@ -429,14 +429,14 @@ const TableSamplePermissions = ({ filterItems, setFilterItems, filters, showGrid
</CardBox> : null
}
<CardBoxModal
title="Please confirm"
title="تأكيد العملية"
buttonColor="info"
buttonLabel={loading ? 'Deleting...' : 'Confirm'}
buttonLabel={loading ? 'جارٍ الحذف...' : 'تأكيد'}
isActive={isModalTrashActive}
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>هل أنت متأكد من حذف هذا العنصر؟</p>
</CardBoxModal>
@ -450,7 +450,7 @@ const TableSamplePermissions = ({ filterItems, setFilterItems, filters, showGrid
<BaseButton
className='me-4'
color='danger'
label={`Delete ${selectedRows.length === 1 ? 'Row' : 'Rows'}`}
label={`حذف ${selectedRows.length === 1 ? 'السجل المحدد' : 'السجلات المحددة'}`}
onClick={() => onDeleteRows(selectedRows)}
/>,
document.getElementById('delete-rows-button'),

View File

@ -165,7 +165,7 @@ const CardPrice_change_logs = ({
))}
{!loading && price_change_logs.length === 0 && (
<div className='col-span-full flex items-center justify-center h-40'>
<p className=''>No data to display</p>
<p className=''>لا توجد بيانات للعرض</p>
</div>
)}
</ul>

View File

@ -118,7 +118,7 @@ const ListPrice_change_logs = ({ price_change_logs, loading, onDelete, currentPa
))}
{!loading && price_change_logs.length === 0 && (
<div className='col-span-full flex items-center justify-center h-40'>
<p className=''>No data to display</p>
<p className=''>لا توجد بيانات للعرض</p>
</div>
)}
</div>

View File

@ -395,12 +395,12 @@ const TableSamplePrice_change_logs = ({ filterItems, setFilterItems, filters, sh
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">إجراء</div>
<BaseButton
className="my-2"
type='reset'
color='danger'
label='Delete'
label='حذف'
onClick={() => {
deleteFilter(filterItem.id)
}}
@ -413,13 +413,13 @@ const TableSamplePrice_change_logs = ({ filterItems, setFilterItems, filters, sh
<BaseButton
className="my-2 mr-3"
color="success"
label='Apply'
label='تطبيق'
onClick={handleSubmit}
/>
<BaseButton
className="my-2"
color='info'
label='Cancel'
label='إلغاء'
onClick={handleReset}
/>
</div>
@ -429,14 +429,14 @@ const TableSamplePrice_change_logs = ({ filterItems, setFilterItems, filters, sh
</CardBox> : null
}
<CardBoxModal
title="Please confirm"
title="تأكيد العملية"
buttonColor="info"
buttonLabel={loading ? 'Deleting...' : 'Confirm'}
buttonLabel={loading ? 'جارٍ الحذف...' : 'تأكيد'}
isActive={isModalTrashActive}
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>هل أنت متأكد من حذف هذا العنصر؟</p>
</CardBoxModal>
@ -450,7 +450,7 @@ const TableSamplePrice_change_logs = ({ filterItems, setFilterItems, filters, sh
<BaseButton
className='me-4'
color='danger'
label={`Delete ${selectedRows.length === 1 ? 'Row' : 'Rows'}`}
label={`حذف ${selectedRows.length === 1 ? 'السجل المحدد' : 'السجلات المحددة'}`}
onClick={() => onDeleteRows(selectedRows)}
/>,
document.getElementById('delete-rows-button'),

View File

@ -117,7 +117,7 @@ const CardRoles = ({
))}
{!loading && roles.length === 0 && (
<div className='col-span-full flex items-center justify-center h-40'>
<p className=''>No data to display</p>
<p className=''>لا توجد بيانات للعرض</p>
</div>
)}
</ul>

View File

@ -86,7 +86,7 @@ const ListRoles = ({ roles, loading, onDelete, currentPage, numPages, onPageChan
))}
{!loading && roles.length === 0 && (
<div className='col-span-full flex items-center justify-center h-40'>
<p className=''>No data to display</p>
<p className=''>لا توجد بيانات للعرض</p>
</div>
)}
</div>

View File

@ -395,12 +395,12 @@ const TableSampleRoles = ({ filterItems, setFilterItems, filters, showGrid }) =>
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">إجراء</div>
<BaseButton
className="my-2"
type='reset'
color='danger'
label='Delete'
label='حذف'
onClick={() => {
deleteFilter(filterItem.id)
}}
@ -413,13 +413,13 @@ const TableSampleRoles = ({ filterItems, setFilterItems, filters, showGrid }) =>
<BaseButton
className="my-2 mr-3"
color="success"
label='Apply'
label='تطبيق'
onClick={handleSubmit}
/>
<BaseButton
className="my-2"
color='info'
label='Cancel'
label='إلغاء'
onClick={handleReset}
/>
</div>
@ -429,14 +429,14 @@ const TableSampleRoles = ({ filterItems, setFilterItems, filters, showGrid }) =>
</CardBox> : null
}
<CardBoxModal
title="Please confirm"
title="تأكيد العملية"
buttonColor="info"
buttonLabel={loading ? 'Deleting...' : 'Confirm'}
buttonLabel={loading ? 'جارٍ الحذف...' : 'تأكيد'}
isActive={isModalTrashActive}
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>هل أنت متأكد من حذف هذا العنصر؟</p>
</CardBoxModal>
@ -450,7 +450,7 @@ const TableSampleRoles = ({ filterItems, setFilterItems, filters, showGrid }) =>
<BaseButton
className='me-4'
color='danger'
label={`Delete ${selectedRows.length === 1 ? 'Row' : 'Rows'}`}
label={`حذف ${selectedRows.length === 1 ? 'السجل المحدد' : 'السجلات المحددة'}`}
onClick={() => onDeleteRows(selectedRows)}
/>,
document.getElementById('delete-rows-button'),

View File

@ -177,7 +177,7 @@ const CardSales_invoice_items = ({
))}
{!loading && sales_invoice_items.length === 0 && (
<div className='col-span-full flex items-center justify-center h-40'>
<p className=''>No data to display</p>
<p className=''>لا توجد بيانات للعرض</p>
</div>
)}
</ul>

View File

@ -126,7 +126,7 @@ const ListSales_invoice_items = ({ sales_invoice_items, loading, onDelete, curre
))}
{!loading && sales_invoice_items.length === 0 && (
<div className='col-span-full flex items-center justify-center h-40'>
<p className=''>No data to display</p>
<p className=''>لا توجد بيانات للعرض</p>
</div>
)}
</div>

View File

@ -395,12 +395,12 @@ const TableSampleSales_invoice_items = ({ filterItems, setFilterItems, filters,
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">إجراء</div>
<BaseButton
className="my-2"
type='reset'
color='danger'
label='Delete'
label='حذف'
onClick={() => {
deleteFilter(filterItem.id)
}}
@ -413,13 +413,13 @@ const TableSampleSales_invoice_items = ({ filterItems, setFilterItems, filters,
<BaseButton
className="my-2 mr-3"
color="success"
label='Apply'
label='تطبيق'
onClick={handleSubmit}
/>
<BaseButton
className="my-2"
color='info'
label='Cancel'
label='إلغاء'
onClick={handleReset}
/>
</div>
@ -429,14 +429,14 @@ const TableSampleSales_invoice_items = ({ filterItems, setFilterItems, filters,
</CardBox> : null
}
<CardBoxModal
title="Please confirm"
title="تأكيد العملية"
buttonColor="info"
buttonLabel={loading ? 'Deleting...' : 'Confirm'}
buttonLabel={loading ? 'جارٍ الحذف...' : 'تأكيد'}
isActive={isModalTrashActive}
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>هل أنت متأكد من حذف هذا العنصر؟</p>
</CardBoxModal>
@ -450,7 +450,7 @@ const TableSampleSales_invoice_items = ({ filterItems, setFilterItems, filters,
<BaseButton
className='me-4'
color='danger'
label={`Delete ${selectedRows.length === 1 ? 'Row' : 'Rows'}`}
label={`حذف ${selectedRows.length === 1 ? 'السجل المحدد' : 'السجلات المحددة'}`}
onClick={() => onDeleteRows(selectedRows)}
/>,
document.getElementById('delete-rows-button'),

View File

@ -37,7 +37,7 @@ const Search = () => {
name='search'
validate={validateSearch}
placeholder='ابحث عن صفحة أو عنصر' dir='rtl'
className={` ${corners} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 p-2 relative ml-2 w-full dark:placeholder-dark-600 ${focusRing} shadow-none`}
className={`${corners} dark:bg-dark-900 ${cardsStyle} dark:border-dark-700 relative ml-2 w-full p-2.5 text-sm font-medium shadow-none transition-all duration-200 ease-out placeholder:font-normal dark:placeholder-dark-600 ${focusRing}`}
/>
{errors.search && touched.search && values.search.length < 2 ? (
<div className='text-red-500 text-sm ml-2 absolute'>{errors.search}</div>

View File

@ -202,7 +202,7 @@ const CardUsers = ({
))}
{!loading && users.length === 0 && (
<div className='col-span-full flex items-center justify-center h-40'>
<p className=''>No data to display</p>
<p className=''>لا توجد بيانات للعرض</p>
</div>
)}
</ul>

View File

@ -145,7 +145,7 @@ const ListUsers = ({ users, loading, onDelete, currentPage, numPages, onPageChan
))}
{!loading && users.length === 0 && (
<div className='col-span-full flex items-center justify-center h-40'>
<p className=''>No data to display</p>
<p className=''>لا توجد بيانات للعرض</p>
</div>
)}
</div>

View File

@ -395,12 +395,12 @@ const TableSampleUsers = ({ filterItems, setFilterItems, filters, showGrid }) =>
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">إجراء</div>
<BaseButton
className="my-2"
type='reset'
color='danger'
label='Delete'
label='حذف'
onClick={() => {
deleteFilter(filterItem.id)
}}
@ -413,13 +413,13 @@ const TableSampleUsers = ({ filterItems, setFilterItems, filters, showGrid }) =>
<BaseButton
className="my-2 mr-3"
color="success"
label='Apply'
label='تطبيق'
onClick={handleSubmit}
/>
<BaseButton
className="my-2"
color='info'
label='Cancel'
label='إلغاء'
onClick={handleReset}
/>
</div>
@ -429,14 +429,14 @@ const TableSampleUsers = ({ filterItems, setFilterItems, filters, showGrid }) =>
</CardBox> : null
}
<CardBoxModal
title="Please confirm"
title="تأكيد العملية"
buttonColor="info"
buttonLabel={loading ? 'Deleting...' : 'Confirm'}
buttonLabel={loading ? 'جارٍ الحذف...' : 'تأكيد'}
isActive={isModalTrashActive}
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>هل أنت متأكد من حذف هذا العنصر؟</p>
</CardBoxModal>
@ -450,7 +450,7 @@ const TableSampleUsers = ({ filterItems, setFilterItems, filters, showGrid }) =>
<BaseButton
className='me-4'
color='danger'
label={`Delete ${selectedRows.length === 1 ? 'Row' : 'Rows'}`}
label={`حذف ${selectedRows.length === 1 ? 'السجل المحدد' : 'السجلات المحددة'}`}
onClick={() => onDeleteRows(selectedRows)}
/>,
document.getElementById('delete-rows-button'),

View File

@ -35,14 +35,57 @@
@apply bg-transparent border border-blue-600 text-blue-600 !important;
}
:root {
--app-font-primary: 'Tajawal', 'Segoe UI', Tahoma, Arial, sans-serif;
--app-transition-fast: 180ms cubic-bezier(0.22, 1, 0.36, 1);
--app-transition-base: 260ms cubic-bezier(0.22, 1, 0.36, 1);
}
html {
scroll-behavior: smooth;
}
html, body {
font-family: 'Tajawal', 'Segoe UI', Tahoma, Arial, sans-serif;
font-family: var(--app-font-primary);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
text-rendering: optimizeLegibility;
}
body,
button,
input,
select,
textarea {
font-family: inherit;
}
h1,
h2,
h3,
h4,
h5,
h6 {
letter-spacing: -0.01em;
}
a,
button,
input,
select,
textarea {
transition:
color var(--app-transition-fast),
background-color var(--app-transition-fast),
border-color var(--app-transition-fast),
box-shadow var(--app-transition-fast),
opacity var(--app-transition-fast),
transform var(--app-transition-fast);
}
.app-rtl {
direction: rtl;
text-align: right;

View File

@ -109,10 +109,10 @@ const EditOrganizations = () => {
return (
<>
<Head>
<title>{getPageTitle('Edit organizations')}</title>
<title>{getPageTitle('تعديل منظمة')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'Edit organizations'} main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'تعديل منظمة'} main>
{''}
</SectionTitleLineWithButton>
<CardBox>
@ -164,9 +164,9 @@ const EditOrganizations = () => {
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/organizations/organizations-list')}/>
<BaseButton type="submit" color="info" label="حفظ" />
<BaseButton type="reset" color="info" outline label="إعادة تعيين" />
<BaseButton type='reset' color='danger' outline label='إلغاء' onClick={() => router.push('/organizations/organizations-list')}/>
</BaseButtons>
</Form>
</Formik>

View File

@ -106,10 +106,10 @@ const EditOrganizationsPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Edit organizations')}</title>
<title>{getPageTitle('تعديل منظمة')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'Edit organizations'} main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'تعديل منظمة'} main>
{''}
</SectionTitleLineWithButton>
<CardBox>
@ -161,9 +161,9 @@ const EditOrganizationsPage = () => {
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/organizations/organizations-list')}/>
<BaseButton type="submit" color="info" label="حفظ" />
<BaseButton type="reset" color="info" outline label="إعادة تعيين" />
<BaseButton type='reset' color='danger' outline label='إلغاء' onClick={() => router.push('/organizations/organizations-list')}/>
</BaseButtons>
</Form>
</Formik>

View File

@ -86,28 +86,28 @@ const OrganizationsTablesPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Organizations')}</title>
<title>{getPageTitle('المنظمات')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="Organizations" main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="المنظمات" main>
{''}
</SectionTitleLineWithButton>
<CardBox className='mb-6' cardBoxClassName='flex flex-wrap'>
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/organizations/organizations-new'} color='info' label='New Item'/>}
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/organizations/organizations-new'} color='info' label='إضافة منظمة'/>}
<BaseButton
className={'mr-3'}
color='info'
label='Filter'
label='تصفية'
onClick={addFilter}
/>
<BaseButton className={'mr-3'} color='info' label='Download CSV' onClick={getOrganizationsCSV} />
<BaseButton className={'mr-3'} color='info' label='تنزيل CSV' onClick={getOrganizationsCSV} />
{hasCreatePermission && (
<BaseButton
color='info'
label='Upload CSV'
label='رفع CSV'
onClick={() => setIsModalActive(true)}
/>
)}

View File

@ -62,10 +62,10 @@ const OrganizationsNew = () => {
return (
<>
<Head>
<title>{getPageTitle('New Item')}</title>
<title>{getPageTitle('إضافة منظمة')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="New Item" main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="إضافة منظمة" main>
{''}
</SectionTitleLineWithButton>
<CardBox>
@ -116,9 +116,9 @@ const OrganizationsNew = () => {
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/organizations/organizations-list')}/>
<BaseButton type="submit" color="info" label="حفظ" />
<BaseButton type="reset" color="info" outline label="إعادة تعيين" />
<BaseButton type='reset' color='danger' outline label='إلغاء' onClick={() => router.push('/organizations/organizations-list')}/>
</BaseButtons>
</Form>
</Formik>

View File

@ -86,28 +86,28 @@ const OrganizationsTablesPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Organizations')}</title>
<title>{getPageTitle('المنظمات')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="Organizations" main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="المنظمات" main>
{''}
</SectionTitleLineWithButton>
<CardBox className='mb-6' cardBoxClassName='flex flex-wrap'>
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/organizations/organizations-new'} color='info' label='New Item'/>}
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/organizations/organizations-new'} color='info' label='إضافة منظمة'/>}
<BaseButton
className={'mr-3'}
color='info'
label='Filter'
label='تصفية'
onClick={addFilter}
/>
<BaseButton className={'mr-3'} color='info' label='Download CSV' onClick={getOrganizationsCSV} />
<BaseButton className={'mr-3'} color='info' label='تنزيل CSV' onClick={getOrganizationsCSV} />
{hasCreatePermission && (
<BaseButton
color='info'
label='Upload CSV'
label='رفع CSV'
onClick={() => setIsModalActive(true)}
/>
)}

View File

@ -33,11 +33,6 @@ const OrganizationsView = () => {
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
@ -46,13 +41,13 @@ const OrganizationsView = () => {
return (
<>
<Head>
<title>{getPageTitle('View organizations')}</title>
<title>{getPageTitle('عرض منظمة')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View organizations')} main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="عرض منظمة" main>
<BaseButton
color='info'
label='Edit'
label='تعديل'
href={`/organizations/organizations-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>

View File

@ -109,10 +109,10 @@ const EditPermissions = () => {
return (
<>
<Head>
<title>{getPageTitle('Edit permissions')}</title>
<title>{getPageTitle('تعديل صلاحية')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'Edit permissions'} main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'تعديل صلاحية'} main>
{''}
</SectionTitleLineWithButton>
<CardBox>
@ -164,9 +164,9 @@ const EditPermissions = () => {
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/permissions/permissions-list')}/>
<BaseButton type="submit" color="info" label="حفظ" />
<BaseButton type="reset" color="info" outline label="إعادة تعيين" />
<BaseButton type='reset' color='danger' outline label='إلغاء' onClick={() => router.push('/permissions/permissions-list')}/>
</BaseButtons>
</Form>
</Formik>

View File

@ -106,10 +106,10 @@ const EditPermissionsPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Edit permissions')}</title>
<title>{getPageTitle('تعديل صلاحية')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'Edit permissions'} main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'تعديل صلاحية'} main>
{''}
</SectionTitleLineWithButton>
<CardBox>
@ -161,9 +161,9 @@ const EditPermissionsPage = () => {
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/permissions/permissions-list')}/>
<BaseButton type="submit" color="info" label="حفظ" />
<BaseButton type="reset" color="info" outline label="إعادة تعيين" />
<BaseButton type='reset' color='danger' outline label='إلغاء' onClick={() => router.push('/permissions/permissions-list')}/>
</BaseButtons>
</Form>
</Formik>

View File

@ -86,28 +86,28 @@ const PermissionsTablesPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Permissions')}</title>
<title>{getPageTitle('الصلاحيات')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="Permissions" main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="الصلاحيات" main>
{''}
</SectionTitleLineWithButton>
<CardBox className='mb-6' cardBoxClassName='flex flex-wrap'>
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/permissions/permissions-new'} color='info' label='New Item'/>}
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/permissions/permissions-new'} color='info' label='إضافة صلاحية'/>}
<BaseButton
className={'mr-3'}
color='info'
label='Filter'
label='تصفية'
onClick={addFilter}
/>
<BaseButton className={'mr-3'} color='info' label='Download CSV' onClick={getPermissionsCSV} />
<BaseButton className={'mr-3'} color='info' label='تنزيل CSV' onClick={getPermissionsCSV} />
{hasCreatePermission && (
<BaseButton
color='info'
label='Upload CSV'
label='رفع CSV'
onClick={() => setIsModalActive(true)}
/>
)}

View File

@ -62,10 +62,10 @@ const PermissionsNew = () => {
return (
<>
<Head>
<title>{getPageTitle('New Item')}</title>
<title>{getPageTitle('إضافة صلاحية')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="New Item" main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="إضافة صلاحية" main>
{''}
</SectionTitleLineWithButton>
<CardBox>
@ -116,9 +116,9 @@ const PermissionsNew = () => {
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/permissions/permissions-list')}/>
<BaseButton type="submit" color="info" label="حفظ" />
<BaseButton type="reset" color="info" outline label="إعادة تعيين" />
<BaseButton type='reset' color='danger' outline label='إلغاء' onClick={() => router.push('/permissions/permissions-list')}/>
</BaseButtons>
</Form>
</Formik>

View File

@ -86,28 +86,28 @@ const PermissionsTablesPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Permissions')}</title>
<title>{getPageTitle('الصلاحيات')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="Permissions" main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="الصلاحيات" main>
{''}
</SectionTitleLineWithButton>
<CardBox className='mb-6' cardBoxClassName='flex flex-wrap'>
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/permissions/permissions-new'} color='info' label='New Item'/>}
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/permissions/permissions-new'} color='info' label='إضافة صلاحية'/>}
<BaseButton
className={'mr-3'}
color='info'
label='Filter'
label='تصفية'
onClick={addFilter}
/>
<BaseButton className={'mr-3'} color='info' label='Download CSV' onClick={getPermissionsCSV} />
<BaseButton className={'mr-3'} color='info' label='تنزيل CSV' onClick={getPermissionsCSV} />
{hasCreatePermission && (
<BaseButton
color='info'
label='Upload CSV'
label='رفع CSV'
onClick={() => setIsModalActive(true)}
/>
)}

View File

@ -33,11 +33,6 @@ const PermissionsView = () => {
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
@ -46,13 +41,13 @@ const PermissionsView = () => {
return (
<>
<Head>
<title>{getPageTitle('View permissions')}</title>
<title>{getPageTitle('عرض صلاحية')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View permissions')} main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="عرض صلاحية" main>
<BaseButton
color='info'
label='Edit'
label='تعديل'
href={`/permissions/permissions-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>

View File

@ -305,10 +305,10 @@ const EditPrice_change_logs = () => {
return (
<>
<Head>
<title>{getPageTitle('Edit price_change_logs')}</title>
<title>{getPageTitle('تعديل سجل تغيير السعر')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'Edit price_change_logs'} main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'تعديل سجل تغيير السعر'} main>
{''}
</SectionTitleLineWithButton>
<CardBox>
@ -706,9 +706,9 @@ const EditPrice_change_logs = () => {
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/price_change_logs/price_change_logs-list')}/>
<BaseButton type="submit" color="info" label="حفظ" />
<BaseButton type="reset" color="info" outline label="إعادة تعيين" />
<BaseButton type='reset' color='danger' outline label='إلغاء' onClick={() => router.push('/price_change_logs/price_change_logs-list')}/>
</BaseButtons>
</Form>
</Formik>

View File

@ -302,10 +302,10 @@ const EditPrice_change_logsPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Edit price_change_logs')}</title>
<title>{getPageTitle('تعديل سجل تغيير السعر')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'Edit price_change_logs'} main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'تعديل سجل تغيير السعر'} main>
{''}
</SectionTitleLineWithButton>
<CardBox>
@ -703,9 +703,9 @@ const EditPrice_change_logsPage = () => {
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/price_change_logs/price_change_logs-list')}/>
<BaseButton type="submit" color="info" label="حفظ" />
<BaseButton type="reset" color="info" outline label="إعادة تعيين" />
<BaseButton type='reset' color='danger' outline label='إلغاء' onClick={() => router.push('/price_change_logs/price_change_logs-list')}/>
</BaseButtons>
</Form>
</Formik>

View File

@ -94,28 +94,28 @@ const Price_change_logsTablesPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Price_change_logs')}</title>
<title>{getPageTitle('سجلات تغيير السعر')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="Price_change_logs" main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="سجلات تغيير السعر" main>
{''}
</SectionTitleLineWithButton>
<CardBox className='mb-6' cardBoxClassName='flex flex-wrap'>
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/price_change_logs/price_change_logs-new'} color='info' label='New Item'/>}
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/price_change_logs/price_change_logs-new'} color='info' label='إضافة سجل تغيير السعر'/>}
<BaseButton
className={'mr-3'}
color='info'
label='Filter'
label='تصفية'
onClick={addFilter}
/>
<BaseButton className={'mr-3'} color='info' label='Download CSV' onClick={getPrice_change_logsCSV} />
<BaseButton className={'mr-3'} color='info' label='تنزيل CSV' onClick={getPrice_change_logsCSV} />
{hasCreatePermission && (
<BaseButton
color='info'
label='Upload CSV'
label='رفع CSV'
onClick={() => setIsModalActive(true)}
/>
)}

View File

@ -175,10 +175,10 @@ const Price_change_logsNew = () => {
return (
<>
<Head>
<title>{getPageTitle('New Item')}</title>
<title>{getPageTitle('إضافة سجل تغيير السعر')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="New Item" main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="إضافة سجل تغيير السعر" main>
{''}
</SectionTitleLineWithButton>
<CardBox>
@ -460,9 +460,9 @@ const Price_change_logsNew = () => {
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/price_change_logs/price_change_logs-list')}/>
<BaseButton type="submit" color="info" label="حفظ" />
<BaseButton type="reset" color="info" outline label="إعادة تعيين" />
<BaseButton type='reset' color='danger' outline label='إلغاء' onClick={() => router.push('/price_change_logs/price_change_logs-list')}/>
</BaseButtons>
</Form>
</Formik>

View File

@ -94,28 +94,28 @@ const Price_change_logsTablesPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Price_change_logs')}</title>
<title>{getPageTitle('سجلات تغيير السعر')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="Price_change_logs" main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="سجلات تغيير السعر" main>
{''}
</SectionTitleLineWithButton>
<CardBox className='mb-6' cardBoxClassName='flex flex-wrap'>
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/price_change_logs/price_change_logs-new'} color='info' label='New Item'/>}
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/price_change_logs/price_change_logs-new'} color='info' label='إضافة سجل تغيير السعر'/>}
<BaseButton
className={'mr-3'}
color='info'
label='Filter'
label='تصفية'
onClick={addFilter}
/>
<BaseButton className={'mr-3'} color='info' label='Download CSV' onClick={getPrice_change_logsCSV} />
<BaseButton className={'mr-3'} color='info' label='تنزيل CSV' onClick={getPrice_change_logsCSV} />
{hasCreatePermission && (
<BaseButton
color='info'
label='Upload CSV'
label='رفع CSV'
onClick={() => setIsModalActive(true)}
/>
)}

View File

@ -33,11 +33,6 @@ const Price_change_logsView = () => {
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
@ -46,13 +41,13 @@ const Price_change_logsView = () => {
return (
<>
<Head>
<title>{getPageTitle('View price_change_logs')}</title>
<title>{getPageTitle('عرض سجل تغيير السعر')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View price_change_logs')} main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="عرض سجل تغيير السعر" main>
<BaseButton
color='info'
label='Edit'
label='تعديل'
href={`/price_change_logs/price_change_logs-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>

View File

@ -165,10 +165,10 @@ const EditRoles = () => {
return (
<>
<Head>
<title>{getPageTitle('Edit roles')}</title>
<title>{getPageTitle('تعديل دور')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'Edit roles'} main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'تعديل دور'} main>
{''}
</SectionTitleLineWithButton>
<CardBox>
@ -317,9 +317,9 @@ const EditRoles = () => {
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/roles/roles-list')}/>
<BaseButton type="submit" color="info" label="حفظ" />
<BaseButton type="reset" color="info" outline label="إعادة تعيين" />
<BaseButton type='reset' color='danger' outline label='إلغاء' onClick={() => router.push('/roles/roles-list')}/>
</BaseButtons>
</Form>
</Formik>

View File

@ -162,10 +162,10 @@ const EditRolesPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Edit roles')}</title>
<title>{getPageTitle('تعديل دور')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'Edit roles'} main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'تعديل دور'} main>
{''}
</SectionTitleLineWithButton>
<CardBox>
@ -314,9 +314,9 @@ const EditRolesPage = () => {
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/roles/roles-list')}/>
<BaseButton type="submit" color="info" label="حفظ" />
<BaseButton type="reset" color="info" outline label="إعادة تعيين" />
<BaseButton type='reset' color='danger' outline label='إلغاء' onClick={() => router.push('/roles/roles-list')}/>
</BaseButtons>
</Form>
</Formik>

View File

@ -86,28 +86,28 @@ const RolesTablesPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Roles')}</title>
<title>{getPageTitle('الأدوار')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="Roles" main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="الأدوار" main>
{''}
</SectionTitleLineWithButton>
<CardBox className='mb-6' cardBoxClassName='flex flex-wrap'>
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/roles/roles-new'} color='info' label='New Item'/>}
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/roles/roles-new'} color='info' label='إضافة دور'/>}
<BaseButton
className={'mr-3'}
color='info'
label='Filter'
label='تصفية'
onClick={addFilter}
/>
<BaseButton className={'mr-3'} color='info' label='Download CSV' onClick={getRolesCSV} />
<BaseButton className={'mr-3'} color='info' label='تنزيل CSV' onClick={getRolesCSV} />
{hasCreatePermission && (
<BaseButton
color='info'
label='Upload CSV'
label='رفع CSV'
onClick={() => setIsModalActive(true)}
/>
)}

View File

@ -94,10 +94,10 @@ const RolesNew = () => {
return (
<>
<Head>
<title>{getPageTitle('New Item')}</title>
<title>{getPageTitle('إضافة دور')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="New Item" main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="إضافة دور" main>
{''}
</SectionTitleLineWithButton>
<CardBox>
@ -218,9 +218,9 @@ const RolesNew = () => {
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/roles/roles-list')}/>
<BaseButton type="submit" color="info" label="حفظ" />
<BaseButton type="reset" color="info" outline label="إعادة تعيين" />
<BaseButton type='reset' color='danger' outline label='إلغاء' onClick={() => router.push('/roles/roles-list')}/>
</BaseButtons>
</Form>
</Formik>

View File

@ -86,28 +86,28 @@ const RolesTablesPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Roles')}</title>
<title>{getPageTitle('الأدوار')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="Roles" main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="الأدوار" main>
{''}
</SectionTitleLineWithButton>
<CardBox className='mb-6' cardBoxClassName='flex flex-wrap'>
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/roles/roles-new'} color='info' label='New Item'/>}
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/roles/roles-new'} color='info' label='إضافة دور'/>}
<BaseButton
className={'mr-3'}
color='info'
label='Filter'
label='تصفية'
onClick={addFilter}
/>
<BaseButton className={'mr-3'} color='info' label='Download CSV' onClick={getRolesCSV} />
<BaseButton className={'mr-3'} color='info' label='تنزيل CSV' onClick={getRolesCSV} />
{hasCreatePermission && (
<BaseButton
color='info'
label='Upload CSV'
label='رفع CSV'
onClick={() => setIsModalActive(true)}
/>
)}

View File

@ -33,11 +33,6 @@ const RolesView = () => {
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
@ -46,13 +41,13 @@ const RolesView = () => {
return (
<>
<Head>
<title>{getPageTitle('View roles')}</title>
<title>{getPageTitle('عرض دور')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View roles')} main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="عرض دور" main>
<BaseButton
color='info'
label='Edit'
label='تعديل'
href={`/roles/roles-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>

View File

@ -333,10 +333,10 @@ const EditSales_invoice_items = () => {
return (
<>
<Head>
<title>{getPageTitle('Edit sales_invoice_items')}</title>
<title>{getPageTitle('تعديل بند الفاتورة')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'Edit sales_invoice_items'} main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'تعديل بند الفاتورة'} main>
{''}
</SectionTitleLineWithButton>
<CardBox>
@ -770,9 +770,9 @@ const EditSales_invoice_items = () => {
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/sales_invoice_items/sales_invoice_items-list')}/>
<BaseButton type="submit" color="info" label="حفظ" />
<BaseButton type="reset" color="info" outline label="إعادة تعيين" />
<BaseButton type='reset' color='danger' outline label='إلغاء' onClick={() => router.push('/sales_invoice_items/sales_invoice_items-list')}/>
</BaseButtons>
</Form>
</Formik>

View File

@ -330,10 +330,10 @@ const EditSales_invoice_itemsPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Edit sales_invoice_items')}</title>
<title>{getPageTitle('تعديل بند الفاتورة')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'Edit sales_invoice_items'} main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'تعديل بند الفاتورة'} main>
{''}
</SectionTitleLineWithButton>
<CardBox>
@ -767,9 +767,9 @@ const EditSales_invoice_itemsPage = () => {
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/sales_invoice_items/sales_invoice_items-list')}/>
<BaseButton type="submit" color="info" label="حفظ" />
<BaseButton type="reset" color="info" outline label="إعادة تعيين" />
<BaseButton type='reset' color='danger' outline label='إلغاء' onClick={() => router.push('/sales_invoice_items/sales_invoice_items-list')}/>
</BaseButtons>
</Form>
</Formik>

View File

@ -94,28 +94,28 @@ const Sales_invoice_itemsTablesPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Sales_invoice_items')}</title>
<title>{getPageTitle('بنود الفاتورة')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="Sales_invoice_items" main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="بنود الفاتورة" main>
{''}
</SectionTitleLineWithButton>
<CardBox className='mb-6' cardBoxClassName='flex flex-wrap'>
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/sales_invoice_items/sales_invoice_items-new'} color='info' label='New Item'/>}
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/sales_invoice_items/sales_invoice_items-new'} color='info' label='إضافة بند الفاتورة'/>}
<BaseButton
className={'mr-3'}
color='info'
label='Filter'
label='تصفية'
onClick={addFilter}
/>
<BaseButton className={'mr-3'} color='info' label='Download CSV' onClick={getSales_invoice_itemsCSV} />
<BaseButton className={'mr-3'} color='info' label='تنزيل CSV' onClick={getSales_invoice_itemsCSV} />
{hasCreatePermission && (
<BaseButton
color='info'
label='Upload CSV'
label='رفع CSV'
onClick={() => setIsModalActive(true)}
/>
)}

View File

@ -190,10 +190,10 @@ const Sales_invoice_itemsNew = () => {
return (
<>
<Head>
<title>{getPageTitle('New Item')}</title>
<title>{getPageTitle('إضافة بند الفاتورة')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="New Item" main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="إضافة بند الفاتورة" main>
{''}
</SectionTitleLineWithButton>
<CardBox>
@ -514,9 +514,9 @@ const Sales_invoice_itemsNew = () => {
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/sales_invoice_items/sales_invoice_items-list')}/>
<BaseButton type="submit" color="info" label="حفظ" />
<BaseButton type="reset" color="info" outline label="إعادة تعيين" />
<BaseButton type='reset' color='danger' outline label='إلغاء' onClick={() => router.push('/sales_invoice_items/sales_invoice_items-list')}/>
</BaseButtons>
</Form>
</Formik>

View File

@ -94,28 +94,28 @@ const Sales_invoice_itemsTablesPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Sales_invoice_items')}</title>
<title>{getPageTitle('بنود الفاتورة')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="Sales_invoice_items" main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="بنود الفاتورة" main>
{''}
</SectionTitleLineWithButton>
<CardBox className='mb-6' cardBoxClassName='flex flex-wrap'>
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/sales_invoice_items/sales_invoice_items-new'} color='info' label='New Item'/>}
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/sales_invoice_items/sales_invoice_items-new'} color='info' label='إضافة بند الفاتورة'/>}
<BaseButton
className={'mr-3'}
color='info'
label='Filter'
label='تصفية'
onClick={addFilter}
/>
<BaseButton className={'mr-3'} color='info' label='Download CSV' onClick={getSales_invoice_itemsCSV} />
<BaseButton className={'mr-3'} color='info' label='تنزيل CSV' onClick={getSales_invoice_itemsCSV} />
{hasCreatePermission && (
<BaseButton
color='info'
label='Upload CSV'
label='رفع CSV'
onClick={() => setIsModalActive(true)}
/>
)}

View File

@ -33,11 +33,6 @@ const Sales_invoice_itemsView = () => {
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
@ -46,13 +41,13 @@ const Sales_invoice_itemsView = () => {
return (
<>
<Head>
<title>{getPageTitle('View sales_invoice_items')}</title>
<title>{getPageTitle('عرض بند الفاتورة')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View sales_invoice_items')} main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="عرض بند الفاتورة" main>
<BaseButton
color='info'
label='Edit'
label='تعديل'
href={`/sales_invoice_items/sales_invoice_items-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>

View File

@ -335,10 +335,10 @@ const EditUsers = () => {
return (
<>
<Head>
<title>{getPageTitle('Edit users')}</title>
<title>{getPageTitle('تعديل مستخدم')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'Edit users'} main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'تعديل مستخدم'} main>
{''}
</SectionTitleLineWithButton>
<CardBox>
@ -779,9 +779,9 @@ const EditUsers = () => {
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/users/users-list')}/>
<BaseButton type="submit" color="info" label="حفظ" />
<BaseButton type="reset" color="info" outline label="إعادة تعيين" />
<BaseButton type='reset' color='danger' outline label='إلغاء' onClick={() => router.push('/users/users-list')}/>
</BaseButtons>
</Form>
</Formik>

View File

@ -332,10 +332,10 @@ const EditUsersPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Edit users')}</title>
<title>{getPageTitle('تعديل مستخدم')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'Edit users'} main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={'تعديل مستخدم'} main>
{''}
</SectionTitleLineWithButton>
<CardBox>
@ -776,9 +776,9 @@ const EditUsersPage = () => {
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/users/users-list')}/>
<BaseButton type="submit" color="info" label="حفظ" />
<BaseButton type="reset" color="info" outline label="إعادة تعيين" />
<BaseButton type='reset' color='danger' outline label='إلغاء' onClick={() => router.push('/users/users-list')}/>
</BaseButtons>
</Form>
</Formik>

View File

@ -92,28 +92,28 @@ const UsersTablesPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Users')}</title>
<title>{getPageTitle('المستخدمون')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="Users" main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="المستخدمون" main>
{''}
</SectionTitleLineWithButton>
<CardBox id="usersList" className='mb-6' cardBoxClassName='flex flex-wrap'>
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/users/users-new'} color='info' label='Add/Invite User'/>}
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/users/users-new'} color='info' label='إضافة مستخدم'/>}
<BaseButton
className={'mr-3'}
color='info'
label='Filter'
label='تصفية'
onClick={addFilter}
/>
<BaseButton className={'mr-3'} color='info' label='Download CSV' onClick={getUsersCSV} />
<BaseButton className={'mr-3'} color='info' label='تنزيل CSV' onClick={getUsersCSV} />
{hasCreatePermission && (
<BaseButton
color='info'
label='Upload CSV'
label='رفع CSV'
onClick={() => setIsModalActive(true)}
/>
)}

View File

@ -190,10 +190,10 @@ const UsersNew = () => {
return (
<>
<Head>
<title>{getPageTitle('New Item')}</title>
<title>{getPageTitle('إضافة مستخدم')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="New Item" main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="إضافة مستخدم" main>
{''}
</SectionTitleLineWithButton>
<CardBox>
@ -521,9 +521,9 @@ const UsersNew = () => {
<BaseDivider />
<BaseButtons>
<BaseButton type="submit" color="info" label="Submit" />
<BaseButton type="reset" color="info" outline label="Reset" />
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/users/users-list')}/>
<BaseButton type="submit" color="info" label="حفظ" />
<BaseButton type="reset" color="info" outline label="إعادة تعيين" />
<BaseButton type='reset' color='danger' outline label='إلغاء' onClick={() => router.push('/users/users-list')}/>
</BaseButtons>
</Form>
</Formik>

View File

@ -92,28 +92,28 @@ const UsersTablesPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Users')}</title>
<title>{getPageTitle('المستخدمون')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="Users" main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="المستخدمون" main>
{''}
</SectionTitleLineWithButton>
<CardBox className='mb-6' cardBoxClassName='flex flex-wrap'>
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/users/users-new'} color='info' label='Add/Invite User'/>}
{hasCreatePermission && <BaseButton className={'mr-3'} href={'/users/users-new'} color='info' label='إضافة مستخدم'/>}
<BaseButton
className={'mr-3'}
color='info'
label='Filter'
label='تصفية'
onClick={addFilter}
/>
<BaseButton className={'mr-3'} color='info' label='Download CSV' onClick={getUsersCSV} />
<BaseButton className={'mr-3'} color='info' label='تنزيل CSV' onClick={getUsersCSV} />
{hasCreatePermission && (
<BaseButton
color='info'
label='Upload CSV'
label='رفع CSV'
onClick={() => setIsModalActive(true)}
/>
)}

View File

@ -33,11 +33,6 @@ const UsersView = () => {
const { id } = router.query;
function removeLastCharacter(str) {
console.log(str,`str`)
return str.slice(0, -1);
}
useEffect(() => {
dispatch(fetch({ id }));
}, [dispatch, id]);
@ -46,13 +41,13 @@ const UsersView = () => {
return (
<>
<Head>
<title>{getPageTitle('View users')}</title>
<title>{getPageTitle('عرض مستخدم')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={removeLastCharacter('View users')} main>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="عرض مستخدم" main>
<BaseButton
color='info'
label='Edit'
label='تعديل'
href={`/users/users-edit/?id=${id}`}
/>
</SectionTitleLineWithButton>