diff --git a/client/src/containers/Setup/SetupSubscription.js b/client/src/containers/Setup/SetupSubscription.js
index 9282b5626..00974e056 100644
--- a/client/src/containers/Setup/SetupSubscription.js
+++ b/client/src/containers/Setup/SetupSubscription.js
@@ -4,7 +4,7 @@ import * as R from 'ramda';
import 'style/pages/Setup/Subscription.scss';
-import SetupSubscriptionForm from './SetupSubscriptionForm';
+import SetupSubscriptionForm from './SetupSubscription/SetupSubscriptionForm';
import { getSubscriptionFormSchema } from './SubscriptionForm.schema';
import withSubscriptionPlansActions from '../Subscriptions/withSubscriptionPlansActions';
@@ -13,13 +13,11 @@ import withSubscriptionPlansActions from '../Subscriptions/withSubscriptionPlans
*/
function SetupSubscription({
// #withSubscriptionPlansActions
- initSubscriptionPlans
+ initSubscriptionPlans,
}) {
React.useEffect(() => {
initSubscriptionPlans();
- }, [
- initSubscriptionPlans
- ]);
+ }, [initSubscriptionPlans]);
// Initial values.
const initialValues = {
@@ -30,10 +28,14 @@ function SetupSubscription({
// Handle form submit.
const handleSubmit = () => {};
- const SubscriptionFormSchema = getSubscriptionFormSchema();
+ // Retrieve momerized subscription form schema.
+ const SubscriptionFormSchema = React.useMemo(
+ () => getSubscriptionFormSchema(),
+ [],
+ );
return (
-
+
+
+
+
+
+ );
+}
diff --git a/client/src/containers/Setup/SetupSubscription/SubscriptionPaymentsMethodsSection.js b/client/src/containers/Setup/SetupSubscription/SubscriptionPaymentsMethodsSection.js
new file mode 100644
index 000000000..7cb66f8a5
--- /dev/null
+++ b/client/src/containers/Setup/SetupSubscription/SubscriptionPaymentsMethodsSection.js
@@ -0,0 +1,19 @@
+import React from 'react';
+import { T } from 'components';
+
+import { PaymentMethodTabs } from '../../Subscriptions/SubscriptionTabs';
+
+export default ({ formik, title, description }) => {
+ return (
+
+ );
+};
diff --git a/client/src/containers/Setup/SetupSubscription/SubscriptionPeriodsSection.js b/client/src/containers/Setup/SetupSubscription/SubscriptionPeriodsSection.js
new file mode 100644
index 000000000..b07731eb7
--- /dev/null
+++ b/client/src/containers/Setup/SetupSubscription/SubscriptionPeriodsSection.js
@@ -0,0 +1,43 @@
+import React from 'react';
+import { Field } from 'formik';
+import * as R from 'ramda';
+
+import { T, SubscriptionPeriods } from 'components';
+
+import withPlan from '../../Subscriptions/withPlan';
+
+const SubscriptionPeriodsEnhanced = R.compose(
+ withPlan(({ plan }) => ({ plan })),
+)(({ plan, ...restProps }) => {
+ return
;
+});
+
+/**
+ * Billing periods.
+ */
+export default function SubscriptionPeriodsSection() {
+ return (
+
+
+
+
+
+
+
+ {({ form: { setFieldValue, values }, field: { value } }) => (
+ {
+ setFieldValue('period', period);
+ }}
+ />
+ )}
+
+
+ );
+}
diff --git a/client/src/containers/Setup/SetupSubscription/SubscriptionPlansSection.js b/client/src/containers/Setup/SetupSubscription/SubscriptionPlansSection.js
new file mode 100644
index 000000000..6fb5aaded
--- /dev/null
+++ b/client/src/containers/Setup/SetupSubscription/SubscriptionPlansSection.js
@@ -0,0 +1,41 @@
+import React from 'react';
+import { Field } from 'formik';
+
+import { T, SubscriptionPlans } from 'components';
+
+import { compose } from 'utils';
+import withPlans from '../../Subscriptions/withPlans';
+
+/**
+ * Billing plans.
+ */
+function SubscriptionPlansSection({ plans }) {
+ return (
+
+
+
+
+
+
+
+ {({ form: { setFieldValue }, field: { value } }) => (
+ {
+ setFieldValue('plan_slug', value);
+ }}
+ />
+ )}
+
+
+ );
+}
+
+export default compose(withPlans(({ plans }) => ({ plans })))(
+ SubscriptionPlansSection,
+);
diff --git a/client/src/containers/Setup/SetupSubscriptionForm.js b/client/src/containers/Setup/SetupSubscriptionForm.js
deleted file mode 100644
index 6116e5e97..000000000
--- a/client/src/containers/Setup/SetupSubscriptionForm.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import React from 'react';
-import { Form } from 'formik';
-
-import BillingPlansForm from 'containers/Subscriptions/BillingPlansForm';
-
-/**
- * Subscription step of wizard setup.
- */
-export default function SetupSubscriptionForm() {
- return (
-
- );
-}
diff --git a/client/src/containers/Setup/WizardSetupSteps.js b/client/src/containers/Setup/WizardSetupSteps.js
index 8b03b0ab0..aecf11de4 100644
--- a/client/src/containers/Setup/WizardSetupSteps.js
+++ b/client/src/containers/Setup/WizardSetupSteps.js
@@ -5,9 +5,7 @@ import { getSetupWizardSteps } from 'common/registerWizard';
function WizardSetupStep({ label, isActive = false }) {
return (
-
- { label }
-
+ {label}
);
}
diff --git a/client/src/containers/Subscriptions/BillingForm.js b/client/src/containers/Subscriptions/BillingForm.js
index 871e94cd9..f20a8898a 100644
--- a/client/src/containers/Subscriptions/BillingForm.js
+++ b/client/src/containers/Subscriptions/BillingForm.js
@@ -1,7 +1,8 @@
import React, { useEffect } from 'react';
-import * as Yup from 'yup';
import { Formik, Form } from 'formik';
import intl from 'react-intl-universal';
+import { If, Alert, T } from 'components';
+
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import 'style/pages/Billing/BillingPage.scss';
@@ -10,8 +11,11 @@ import { MasterBillingTabs } from './SubscriptionTabs';
import withBillingActions from './withBillingActions';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
+import withSubscriptionPlansActions from './withSubscriptionPlansActions';
import { compose } from 'utils';
+import { getBillingFormValidationSchema } from './utils';
+import withSubscriptions from './withSubscriptions';
/**
* Billing form.
@@ -20,26 +24,30 @@ function BillingForm({
// #withDashboardActions
changePageTitle,
- //#withBillingActions
+ // #withBillingActions
requestSubmitBilling,
+
+ initSubscriptionPlans,
+
+ // #withSubscriptions
+ isSubscriptionInactive,
}) {
useEffect(() => {
changePageTitle(intl.get('billing'));
}, [changePageTitle]);
- const validationSchema = Yup.object().shape({
- plan_slug: Yup.string()
- .required(),
- period: Yup.string().required(),
- license_code: Yup.string().trim(),
- });
+ React.useEffect(() => {
+ initSubscriptionPlans();
+ }, [initSubscriptionPlans]);
+ // Initial values.
const initialValues = {
plan_slug: 'free',
period: 'month',
license_code: '',
};
+ // Handle form submitting.
const handleSubmit = (values, { setSubmitting }) => {
requestSubmitBilling(values)
.then((response) => {
@@ -53,20 +61,34 @@ function BillingForm({
return (
+
+ }
+ description={}
+ />
+
+
- {({ isSubmitting, handleSubmit }) => (
-
- )}
+
);
}
-export default compose(withDashboardActions, withBillingActions)(BillingForm);
+export default compose(
+ withDashboardActions,
+ withBillingActions,
+ withSubscriptionPlansActions,
+ withSubscriptions(
+ ({ isSubscriptionInactive }) => ({ isSubscriptionInactive }),
+ 'main',
+ ),
+)(BillingForm);
diff --git a/client/src/containers/Subscriptions/BillingPeriod.js b/client/src/containers/Subscriptions/BillingPeriod.js
index 4b3b33922..4f2a90e5a 100644
--- a/client/src/containers/Subscriptions/BillingPeriod.js
+++ b/client/src/containers/Subscriptions/BillingPeriod.js
@@ -15,12 +15,14 @@ import { saveInvoke } from 'utils';
function BillingPeriod({
// #ownProps
label,
- currencyCode,
value,
selectedOption,
onSelected,
period,
+
+ // #withPlan
price,
+ currencyCode,
}) {
const handlePeriodClick = () => {
saveInvoke(onSelected, value);
diff --git a/client/src/containers/Subscriptions/BillingPeriodsInput.js b/client/src/containers/Subscriptions/BillingPeriodsInput.js
index 8421bb8c7..29ace1f48 100644
--- a/client/src/containers/Subscriptions/BillingPeriodsInput.js
+++ b/client/src/containers/Subscriptions/BillingPeriodsInput.js
@@ -1,42 +1,46 @@
import React from 'react';
import { Field } from 'formik';
-import BillingPeriod from './BillingPeriod';
+import * as R from 'ramda';
-import withPlans from './withPlans';
+import { T, SubscriptionPeriods } from 'components';
-import { compose } from 'utils';
+import withPlan from './withPlan';
+
+/**
+ * Sunscription periods enhanced.
+ */
+const SubscriptionPeriodsEnhanced = R.compose(
+ withPlan(({ plan }) => ({ plan })),
+)(({ plan, ...restProps }) => {
+ return
;
+});
/**
* Billing periods.
*/
-function BillingPeriods({ title, description, plansPeriods }) {
+export default function BillingPeriods() {
return (
- {title}
+
+
+
- {({ form: { setFieldValue, values } }) => (
-
- {plansPeriods.map((period) => (
- setFieldValue('period', value)}
- selectedOption={values.period}
- />
- ))}
-
+ {({ field: { value }, form: { values, setFieldValue } }) => (
+ {
+ setFieldValue('period', period);
+ }}
+ />
)}
);
}
-
-export default compose(withPlans(({ plansPeriods }) => ({ plansPeriods })))(
- BillingPeriods,
-);
diff --git a/client/src/containers/Subscriptions/BillingPlan.js b/client/src/containers/Subscriptions/BillingPlan.js
index c15c450ae..4fe2cf64e 100644
--- a/client/src/containers/Subscriptions/BillingPlan.js
+++ b/client/src/containers/Subscriptions/BillingPlan.js
@@ -3,8 +3,6 @@ import classNames from 'classnames';
import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
-import 'style/pages/Subscription/PlanRadio.scss';
-
import { saveInvoke } from 'utils';
/**
@@ -32,9 +30,7 @@ export default function BillingPlan({
onClick={handlePlanClick}
>
-
- {intl.get('plan_radio_name', { name: name })}
-
+
{name}
diff --git a/client/src/containers/Subscriptions/BillingPlansForm.js b/client/src/containers/Subscriptions/BillingPlansForm.js
index 3819d9286..866acd185 100644
--- a/client/src/containers/Subscriptions/BillingPlansForm.js
+++ b/client/src/containers/Subscriptions/BillingPlansForm.js
@@ -1,12 +1,10 @@
import React from 'react';
-import { FormattedMessage as T } from 'components';
-import intl from 'react-intl-universal';
import 'style/pages/Subscription/BillingPlans.scss';
-import BillingPlansInput from 'containers/Subscriptions/BillingPlansInput';
-import BillingPeriodsInput from 'containers/Subscriptions/BillingPeriodsInput';
-import BillingPaymentMethod from 'containers/Subscriptions/BillingPaymentMethod';
+import BillingPlansInput from './BillingPlansInput';
+import BillingPeriodsInput from './BillingPeriodsInput';
+import BillingPaymentMethod from './BillingPaymentMethod';
/**
* Billing plans form.
@@ -14,18 +12,9 @@ import BillingPaymentMethod from 'containers/Subscriptions/BillingPaymentMethod'
export default function BillingPlansForm() {
return (
- }
- />
- }
- />
- }
- />
+
+
+
);
}
diff --git a/client/src/containers/Subscriptions/BillingPlansInput.js b/client/src/containers/Subscriptions/BillingPlansInput.js
index abdb8d6a9..58ad45bc6 100644
--- a/client/src/containers/Subscriptions/BillingPlansInput.js
+++ b/client/src/containers/Subscriptions/BillingPlansInput.js
@@ -1,6 +1,6 @@
import React from 'react';
-import { FastField, Field } from 'formik';
-import BillingPlan from './BillingPlan';
+import { Field } from 'formik';
+import { T, SubscriptionPlans } from 'components';
import withPlans from './withPlans';
import { compose } from 'utils';
@@ -11,27 +11,24 @@ import { compose } from 'utils';
function BillingPlans({ plans, title, description, selectedOption }) {
return (
- {title}
+
+
+
{({ form: { setFieldValue }, field: { value } }) => (
-
- {plans.map((plan) => (
- setFieldValue('plan_slug', value)}
- selectedOption={value}
- />
- ))}
-
+ {
+ setFieldValue('plan_slug', value);
+ }}
+ />
)}
diff --git a/client/src/containers/Subscriptions/BillingTab.js b/client/src/containers/Subscriptions/BillingTab.js
index 36c3abe06..9212c6f50 100644
--- a/client/src/containers/Subscriptions/BillingTab.js
+++ b/client/src/containers/Subscriptions/BillingTab.js
@@ -1,10 +1,6 @@
import React from 'react';
-import BillingPlansForm from 'containers/Subscriptions/BillingPlansForm';
+import BillingPlansForm from './BillingPlansForm';
export default function BillingTab() {
- return (
-
-
-
- );
+ return (
);
}
\ No newline at end of file
diff --git a/client/src/containers/Subscriptions/SubscriptionTabs.js b/client/src/containers/Subscriptions/SubscriptionTabs.js
index 9280f2d09..212684d05 100644
--- a/client/src/containers/Subscriptions/SubscriptionTabs.js
+++ b/client/src/containers/Subscriptions/SubscriptionTabs.js
@@ -16,11 +16,7 @@ export const MasterBillingTabs = ({ formik }) => {
id={'billing'}
panel={
}
/>
-
+
);
@@ -43,11 +39,7 @@ export const PaymentMethodTabs = ({ formik }) => {
id={'credit_card'}
disabled={true}
/>
-
+
);
diff --git a/client/src/containers/Subscriptions/billingPaymentmethod.js b/client/src/containers/Subscriptions/billingPaymentmethod.js
index 3c22db94c..5c180cf38 100644
--- a/client/src/containers/Subscriptions/billingPaymentmethod.js
+++ b/client/src/containers/Subscriptions/billingPaymentmethod.js
@@ -1,11 +1,13 @@
import React from 'react';
+
+import { T } from 'components';
import { PaymentMethodTabs } from './SubscriptionTabs';
export default ({ formik, title, description }) => {
return (
- { title }
- { description }
+
+
diff --git a/client/src/containers/Subscriptions/utils.js b/client/src/containers/Subscriptions/utils.js
new file mode 100644
index 000000000..76275083e
--- /dev/null
+++ b/client/src/containers/Subscriptions/utils.js
@@ -0,0 +1,8 @@
+import * as Yup from 'yup';
+
+export const getBillingFormValidationSchema = () =>
+ Yup.object().shape({
+ plan_slug: Yup.string().required(),
+ period: Yup.string().required(),
+ license_code: Yup.string().trim(),
+ });
diff --git a/client/src/containers/Subscriptions/withPlans.js b/client/src/containers/Subscriptions/withPlans.js
index 38ca3f5c5..1d73f5801 100644
--- a/client/src/containers/Subscriptions/withPlans.js
+++ b/client/src/containers/Subscriptions/withPlans.js
@@ -1,17 +1,14 @@
import { connect } from 'react-redux';
import {
getPlansSelector,
- getPlansPeriodsSelector,
} from 'store/plans/plans.selectors';
export default (mapState) => {
const mapStateToProps = (state, props) => {
const getPlans = getPlansSelector();
- const getPlansPeriods = getPlansPeriodsSelector();
const mapped = {
plans: getPlans(state, props),
- plansPeriods: getPlansPeriods(state, props),
};
return mapState ? mapState(mapped, state, props) : mapped;
};
diff --git a/client/src/containers/Subscriptions/withSubscriptionss.js b/client/src/containers/Subscriptions/withSubscriptionss.js
new file mode 100644
index 000000000..ce73ac423
--- /dev/null
+++ b/client/src/containers/Subscriptions/withSubscriptionss.js
@@ -0,0 +1,19 @@
+import { connect } from 'react-redux';
+import {
+ isSubscriptionsInactiveFactory,
+ isSubscriptionsActiveFactory
+} from 'store/subscription/subscription.selectors';
+
+export default (mapState) => {
+ const isSubscriptionsInactive = isSubscriptionsInactiveFactory();
+ const isSubscriptionsActive = isSubscriptionsActiveFactory();
+
+ const mapStateToProps = (state, props) => {
+ const mapped = {
+ isSubscriptionsInactive: isSubscriptionsInactive(state, props),
+ isSubscriptionsActive: isSubscriptionsActive(state, props),
+ };
+ return (mapState) ? mapState(mapped, state, props) : mapped;
+ };
+ return connect(mapStateToProps);
+};
\ No newline at end of file
diff --git a/client/src/hooks/query/settings.js b/client/src/hooks/query/settings.js
index 8520e4bab..545dc8eb8 100644
--- a/client/src/hooks/query/settings.js
+++ b/client/src/hooks/query/settings.js
@@ -23,23 +23,18 @@ export function useSaveSettings(props) {
function useSettingsQuery(key, query, props) {
const setSettings = useSetSettings();
- const state = useRequestQuery(
+ return useRequestQuery(
key,
{ method: 'get', url: 'settings', params: query },
{
select: (res) => res.data.settings,
defaultData: [],
+ onSuccess: (settings) => {
+ setSettings(settings);
+ },
...props,
},
);
-
- useEffect(() => {
- if (state.isSuccess) {
- setSettings(state.data);
- }
- }, [state.data, state.isSuccess, setSettings]);
-
- return state.data;
}
/**
diff --git a/client/src/lang/ar-ly/index.json b/client/src/lang/ar-ly/index.json
index e54d2ae5e..b3caa5d11 100644
--- a/client/src/lang/ar-ly/index.json
+++ b/client/src/lang/ar-ly/index.json
@@ -584,7 +584,7 @@
"payment_mades": "سندات الموردين",
"subscription": "الاشتراك",
"plan_slug": "سبيكة خطة",
- "billing": "الفواتير",
+ "billing": "الاشتراك",
"the_billing_has_been_created_successfully": "تم إنشاء الفواتير بنجاح.",
"select_a_plan": "حدد الباقة",
"choose_your_billing": "اختر مدة الدفع",
@@ -1114,12 +1114,10 @@
"filter_": "البحث...",
"all_rights_reserved": "© {pre}-{current} كل الحقوق محفوظة.",
"congrats_your_account_has_been_created_and_invited": "مبروك! تم إنشاء حسابك ودعوتك إلى
{organization_name} بنجاح.",
- "it_s_time_to_make_your_accounting_really_simple": "حان الوقت لجعل عملية المحاسبة الخاصة بك بسيطة واكتر دقة!",
+
"while_we_set_up_your_account_please_remember_to_verify_your_account": "أثناء قيامنا بإعداد حسابك ، يرجى تذكر التحقق من حسابك بالنقر فوق الارتباط الذي أرسلناه إلى عنوان بريدك الإلكتروني المسجل",
- "something_went_wrong": "هناك خطأ ما!",
- "please_refresh_the_page": "يرجى تحديث الصفحة",
- "waiting_to_redirect": "في انتظار إعادة التوجيه",
- "refresh_the_page_if_redirect_not_worked": "قم بتحديث الصفحة إذا لم تنجح إعادة التوجيه.",
+
+
"blog": "المدونة",
"support": "الدعم النفي",
"service_status": "حالة الخدمة",
@@ -1220,6 +1218,67 @@
"pdf_preview.preview.button": "معاينة",
"invoice_preview.dialog.title": "معاينة فاتورة PDF",
"estimate_preview.dialog.title": "معاينة عرض PDF",
- "receipt_preview.dialog.title":"معاينة إيصال PDF"
+ "receipt_preview.dialog.title":"معاينة إيصال PDF",
+ "edit_contact": "Edit {name}",
+ "item.sell_description": "Sell description",
+ "item.purchase_description": "Purchase description",
+ "closed_date": "Closed date",
+ "payment_made.details.payment_number": "Payment #",
+ "payment_receive.details.payment_number": "Payment #",
+ "estimate.details.estimate_number": "Estimate #",
+ "receipt.details.receipt_number": "Receipt #",
+ "bill.details.bill_number": "Bill #",
+ "setup.left_side.title": "سجل منشأة جديدة الأن.",
+ "setup.left_side.description": "حسابك علي Bigcapital",
+ "setup.left_side.footer_help": "نحن هنا للمساعدة!",
+ "setup.plan.plans": "الخطط والدفع",
+ "setup.plan.initializing": "التهيئة",
+ "setup.plan.getting_started": "البدء",
+ "setup.plan.congrats": "تهانينا",
+ "setup.plans.select_plan.description": "الرجاء إدخال طريقة الدفع المفضلة لديك أدناه. يمكنك استخدام بطاقة الائتمان / الخصم أو الدفع المسبق من خلال PayPal. ",
+ "setup.plans.select_plan.title": "اختر الخطة",
+ "setup.plans.select_period.title": "اختر الفترة",
+ "setup.plans.select_period.description": "يمكن تسديد الخطة شهرياً او سنوياً.",
+ "setup.plans.payment_methods.title": "طرق الدفع",
+ "setup.plans.payment_methods.description": "",
+ "setup.initializing.title": "حان الوقت لجعل عملية المحاسبة الخاصة بك بسيطة واكتر دقة!",
+ "setup.initializing.description": "أثناء قيامنا بإعداد حسابك ، يرجى تذكر التحقق من حسابك بالنقر فوق الارتباط الذي أرسلناه إلى عنوان بريدك الإلكتروني المسجل",
+ "setup.initializing.waiting_to_redirect": "في انتظار إعادة التوجيه",
+ "setup.initializing.refresh_the_page_if_redirect_not_worked": "قم بتحديث الصفحة إذا لم تنجح إعادة التوجيه.",
+ "setup.initializing.something_went_wrong": "هناك خطأ ما!",
+ "setup.initializing.please_refresh_the_page": "يرجى تحديث الصفحة",
+ "setup.organization.title": "دعنا نبدأ",
+ "setup.organization.description": "أخبر النظام قليلاً عن مؤسستك.",
+ "plan.essential.title": "الاساسية",
+ "plan.plus.title": "الاضافية",
+ "plan.professional.title": "الاحترافية",
+ "plan.feature.sale_purchase_invoice": "فواتير البيع والشراء.",
+ "plan.feature.receivable_payable_accounts": "حسابات العملاء والموردين.",
+ "plan.feature.expenses_tracking": "تتبع المصروفات",
+ "plan.feature.manual_journal": "القيود اليدوية",
+ "plan.feature.financial_reports": "القوائم المالية",
+ "plan.feature.one_user_with_accountant": "لمستخدم واحد والمحاسب",
+ "plan.feature.all_capital_essential": "جميع مميزات الباقة الاساسية",
+ "plan.feature.multi_currency": "تعدد العملات",
+ "plan.feature.purchase_sell_orders": "أوامر الشراء والبيع.",
+ "plan.feature.multi_inventory_managment": "تعدد المخازن.",
+ "plan.feature.three_users": "ثلاثة مستخدمين مع المحاسب",
+ "plan.feature.advanced_financial_reports": "تقارير المالية المتقدمة",
+ "plan.feature.tracking_multi_locations": "تتبع الفروع والمواقع",
+ "plan.feture.all_capital_professional_features": "جميع مميزات الباقة الاحترافية",
+ "plan.feature.projects_accounting": "محاسبة المشاريع والجداول الزمنية",
+ "plan.feature.accounting_dimensions": "محاسبة ثلاثية الابعاد",
+ "plan.monthly": "شهريا",
+ "plan.yearly": "سنوياً",
+ "payment_via_voucher.success_message": "تم الدفع وتجديد واشتراكك بنجاح.",
+ "payment_via_voucher.license_code_not_valid": "رقم الرخصة غير صالح ، يرجي المحاولة مرة أخرى",
+ "payment_via_voucher.dialog.description": "الرجاء إدخال رقم الرخصة التي استلمتها عند تجديد او طلب الاشتراك .",
+ "setup.organization.note_you_can_change_your_preferences": "ملاحظة: يمكنك تغيير تفضيلاتك لاحقًا في لوحة التحكم ، إذا لزم الأمر.",
+ "setup.congrats.title": "تهانينا! حسابك جاهز للعمل",
+ "setup.congrats.description": "تهانينا ، تم إعداد مؤسستك بنجاح. يمكنك البدء في العمل بمجرد الانتقال إلى لوحة التحكم.",
+ "setup.congrats.go_to_dashboard": "اذهب إلي لوحة التحكم",
+ "billing.suspend_message.title": "حسابك معلق :(",
+ "billing.suspend_message.description": "تم تعليق حسابك بسبب انتهاء فترة الاشتراك. الرجاء تجديد الاشتراك لتفعيل الحساب.",
+ "dashboard.subscription_msg.period_over": "انتهت فترة الاشتراك"
}
diff --git a/client/src/lang/en/index.json b/client/src/lang/en/index.json
index cee6f8be1..c4c701d8c 100644
--- a/client/src/lang/en/index.json
+++ b/client/src/lang/en/index.json
@@ -578,7 +578,6 @@
"plan_slug": "Plan slug",
"billing": "Billing",
"the_billing_has_been_created_successfully": "The billing has been created successfully.",
- "select_a_plan": "Select a plan",
"choose_your_billing": "Choose your billing",
"payment_methods": "Payment methods",
"usage": "Usage",
@@ -591,7 +590,6 @@
"yearly": "Yearly",
"license_code": "License Code",
"year": "Year",
- "please_enter_your_preferred_payment_method": "Please enter your preferred payment method below. You can use a credit / debit card or prepay through PayPal. ",
"cards_will_be_charged": "Cards will be charged either at the end of the month or whenever your balance exceeds the usage threshold. All major credit / debit cards accepted.",
"license_number": "License number",
"subscribe": "Subscribe",
@@ -616,20 +614,15 @@
"purchasable": "Purchasable",
"sell_account": "Sell Account",
"cost_account": "Cost Account",
- "register_a_new_organization_now": "Register a New Organization now!.",
- "you_have_a_bigcapital_account": "You have a Bigcapital account ",
"contact_us_technical_support": "Contact us - Technical Support",
- "let_s_get_started": "Let’s Get Started",
- "tell_the_system_a_little_bit_about_your_organization": "Tell the system a little bit about your organization.",
"organization_details": "Organization details",
"financial_starting_date": "Financial starting date ",
- "note_you_can_change_your_preferences_later_in_dashboard_if_needed": "Note: You can change your preferences later in dashboard, if needed.",
+
"save_continue": "Save & Continue",
"organization_register": "Organization Register",
"fiscal_year_": "Fiscal year",
"welcome": "Welcome ",
"sign_out": "Sign out",
- "we_re_here_to_help": "We’re Here to Help!",
"date_start_": "Date start",
"something_wentwrong": "Something went wrong.",
"license_code_": "License code",
@@ -906,7 +899,6 @@
"accounting": "Accounting",
"system": "SYSTEM",
"it_s_time_to_send_estimates_to_your_customers": "It's time to send estimates to your customers",
- "it_is_a_long_established_fact_that_a_reader": "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.",
"new_sale_estimate": "New sale estimate",
"learn_more": "Learn more",
"back_to_list": "Back to list.",
@@ -1068,8 +1060,7 @@
"products_you_buy_and_or_sell": "
Inventory : Products you buy and/or sell and that you track quantities of.",
"products_you_buy_and_or_sell_but_don_t_need": "
Non-Inventory: Products you buy and/or sell but don’t need to (or can’t) track quantities of, for example, nuts and bolts used in an installation.",
"there_is_no_items_in_the_table_yet": "There is no items in the table yet.",
- "congrats_you_are_ready_to_go": "Congrats! You are ready to go",
- "go_to_dashboard": "Go to dashboard",
+
"mr": "Mr.",
"mrs": "Mrs.",
"ms": "Ms.",
@@ -1101,25 +1092,13 @@
"filter_": "Filter...",
"all_rights_reserved": "© {pre}-{current} All Rights Reserved.",
"congrats_your_account_has_been_created_and_invited": "Congrats! Your account has been created and invited to
{organization_name} organization successfully.",
- "it_s_time_to_make_your_accounting_really_simple": "It's time to make your accounting really simple!",
- "while_we_set_up_your_account_please_remember_to_verify_your_account": "while we set up your account, please remember to verify your account by clicking on the link we sent to your registered email address",
"something_went_wrong": "Something went wrong!",
- "please_refresh_the_page": "Please refresh the page",
- "waiting_to_redirect": "Waiting to redirect",
- "refresh_the_page_if_redirect_not_worked": "Refresh the page if redirect not worked.",
"blog": "Blog",
"support": "Support",
"service_status": "Service Status",
"pricing": "Pricing",
"reseller_partner": "Reseller Partner",
"docs": "Docs",
- "Pleasse enter your voucher number that you received from reseller.": "Pleasse enter your voucher number that you received from reseller.",
- "Sale and purchase invoices.": "Sale and purchase invoices.",
- "Customers/vendors accounts.": "Customers/vendors accounts.",
- "Expenses tracking.": "Expenses tracking.",
- "Manual journals.": "Manual journals.",
- "Financial reports.": "Financial reports.",
- "All Capital Starter features.": "All Capital Starter features.",
"Multi-currency.": "Multi-currency.",
"Purchase and sell orders.": "Purchase and sell orders.",
"Inventory management.": "Inventory management.",
@@ -1129,14 +1108,13 @@
"Track multi-branches and locations.": "Track multi-branches and locations.",
"Projects accounting and timesheets.": "Projects accounting and timesheets.",
"Accounting dimensions.": "Accounting dimensions.",
- "For one user and accountant.": "For one user and accountant.",
"Monthly": "Monthly",
"Yearly": "Yearly",
"Plans & Payment": "Plans & Payment",
"Initializing": "Initializing",
"Getting started": "Getting started",
"Congratulations": "Congratulations",
- "payment_has_been_done_successfully": "Payment has been done successfully.",
+
"manual_journal_number": "Manual journal {number}",
"conditions_and_terms": "Conditions and terms",
"allocate_landed_coast": "Allocate landed cost",
@@ -1167,12 +1145,12 @@
"Landed": "Landed",
"This options allows you to be able to add additional cost eg. freight then allocate cost to the items in your bills.": "This options allows you to be able to add additional cost eg. freight then allocate cost to the items in your bills.",
"Once your delete this located landed cost, you won't be able to restore it later, Are your sure you want to delete this transaction?": "Once your delete this located landed cost, you won't be able to restore it later, Are your sure you want to delete this transaction?",
- "journal_entries":"Journal entries",
- "contact":"Contact",
- "invoice_details":"Invoice details",
- "receipt_details":"Receipt details",
- "payment_receive_details":"Payment receive details",
- "payment_made_details":"Payment made details",
+ "journal_entries": "Journal entries",
+ "contact": "Contact",
+ "invoice_details": "Invoice details",
+ "receipt_details": "Receipt details",
+ "payment_receive_details": "Payment receive details",
+ "payment_made_details": "Payment made details",
"New item category": "New item category",
"New service": "New service",
"New inventory item": "New inventory item",
@@ -1182,10 +1160,10 @@
"New tasks": "New tasks",
"sorry_about_that_something_went_wrong": "Sorry about that! Something went wrong",
"if_the_problem_stuck_please_contact_us_as_soon_as_possible": "If the problem stuck, please contact us as soon as possible.",
- "non-inventory":"Non-Inventory",
- "terms_conditions":"Terms conditions",
- "your_invoice_numbers_are_set_on_auto_increment_mod_are_you_sure_changing_this_setting":"Your invoice numbers are set on auto-increment mod. Are you sure changing this setting?",
- "auto_incrementing_number":"Auto-incrementing number",
+ "non-inventory": "Non-Inventory",
+ "terms_conditions": "Terms conditions",
+ "your_invoice_numbers_are_set_on_auto_increment_mod_are_you_sure_changing_this_setting": "Your invoice numbers are set on auto-increment mod. Are you sure changing this setting?",
+ "auto_incrementing_number": "Auto-incrementing number",
"inventory_adjustment.publish.success_message": "The inventory adjustment has been published successfully.",
"inventory_adjustment.publish.alert_message": "Are you sure you want to publish this inventory adjustment?",
"the_contact_has_been_activated_successfully": "The contact has been inactivated successfully.",
@@ -1207,15 +1185,67 @@
"pdf_preview.download.button": "Download",
"pdf_preview.preview.button": "Preview",
"invoice_preview.dialog.title": "Invoice PDF Preview",
- "estimate_preview.dialog.title":"Estimate PDF Preview",
- "receipt_preview.dialog.title":"Receipt PDF Preview",
- "edit_contact":"Edit {name}",
+ "estimate_preview.dialog.title": "Estimate PDF Preview",
+ "receipt_preview.dialog.title": "Receipt PDF Preview",
+ "edit_contact": "Edit {name}",
"item.sell_description": "Sell description",
"item.purchase_description": "Purchase description",
- "closed_date":"Closed date",
+ "closed_date": "Closed date",
"payment_made.details.payment_number": "Payment #",
"payment_receive.details.payment_number": "Payment #",
"estimate.details.estimate_number": "Estimate #",
"receipt.details.receipt_number": "Receipt #",
- "bill.details.bill_number": "Bill #"
+ "bill.details.bill_number": "Bill #",
+ "setup.left_side.title": "Register a New Organization now!.",
+ "setup.left_side.description": "You have a Bigcapital account",
+ "setup.left_side.footer_help": "We’re Here to Help!",
+ "setup.plan.plans": "Plans & Payment",
+ "setup.plan.initializing": "Initializing",
+ "setup.plan.getting_started": "Getting started",
+ "setup.plan.congrats": "Congratulations",
+ "setup.plans.select_plan.description": "Please enter your preferred payment method below. You can use a credit / debit card or prepay through PayPal. ",
+ "setup.plans.select_plan.title": "Select a plan",
+ "setup.plans.select_period.title": "Plan period",
+ "setup.plans.select_period.description": "The plan could be billed monthly or annually.",
+ "setup.plans.payment_methods.title": "Payment methods",
+ "setup.plans.payment_methods.description": "",
+ "setup.initializing.title": "It's time to make your accounting really simple!",
+ "setup.initializing.description": "while we set up your account, please remember to verify your account by clicking on the link we sent to your registered email address",
+ "setup.initializing.waiting_to_redirect": "Waiting to redirect",
+ "setup.initializing.refresh_the_page_if_redirect_not_worked": "Refresh the page if redirect not worked.",
+ "setup.initializing.something_went_wrong": "Something went wrong!",
+ "setup.initializing.please_refresh_the_page": "Please refresh the page",
+ "setup.organization.title": "Let’s Get Started",
+ "setup.organization.description": "Tell the system a little bit about your organization.",
+ "plan.professional.title": "Pro",
+ "plan.essential.title": "Essential",
+ "plan.plus.title": "Plus+",
+ "plan.feature.sale_purchase_invoice": "Sale and purchase invoices.",
+ "plan.feature.receivable_payable_accounts": "Customers/vendors accounts.",
+ "plan.feature.expenses_tracking": "Expenses tracking",
+ "plan.feature.manual_journal": "Manual journals.",
+ "plan.feature.financial_reports": "Financial reports.",
+ "plan.feature.one_user_with_accountant": "For one user and accountant",
+ "plan.feture.all_capital_professional_features": "All Capital Pro features.",
+ "plan.feature.multi_currency": "Multi-currency.",
+ "plan.feature.purchase_sell_orders": "Purchase and sell orders.",
+ "plan.feature.multi_inventory_managment": "Mutli-inventory managment.",
+ "plan.feature.three_users": "Three users with your accountant",
+ "plan.feature.advanced_financial_reports": "Advanced financial reports",
+ "plan.feature.tracking_multi_locations": "Track multi-branches and locations",
+ "plan.feature.all_capital_essential": "All Capital Essential features.",
+ "plan.feature.projects_accounting": "Projects accounting and timesheets",
+ "plan.feature.accounting_dimensions": "Accounting dimensions.",
+ "plan.monthly": "Monthly",
+ "plan.yearly": "Yearly",
+ "payment_via_voucher.success_message": "Payment has been done successfully.",
+ "payment_via_voucher.license_code_not_valid": "The license code is not valid, please try agin.",
+ "payment_via_voucher.dialog.description": "Pleasse enter your voucher number that you received from reseller.",
+ "setup.organization.note_you_can_change_your_preferences": "Note: You can change your preferences later in dashboard, if needed.",
+ "setup.congrats.title": "Congrats! You are ready to go",
+ "setup.congrats.description": "Congrats, Your organization is set up successfully. you can start working once go to dashboard.",
+ "setup.congrats.go_to_dashboard": "Go to dashboard",
+ "billing.suspend_message.title": "Your account is suspended :(",
+ "billing.suspend_message.description": "Your account has been suspended due to the expiration of the subscription period. Please renew the subscription to activate the account.",
+ "dashboard.subscription_msg.period_over": "Subscription period is over"
}
\ No newline at end of file
diff --git a/client/src/routes/dashboard.js b/client/src/routes/dashboard.js
index 89b1b1a5a..eed0bcae3 100644
--- a/client/src/routes/dashboard.js
+++ b/client/src/routes/dashboard.js
@@ -3,10 +3,14 @@ import { lazy } from 'react';
import intl from 'react-intl-universal';
import { RESOURCES_TYPES } from '../common/resourcesTypes';
+
+const SUBSCRIPTION_TYPE = {
+ MAIN: 'main',
+}
// const BASE_URL = '/dashboard';
export const getDashboardRoutes = () => [
- // // Accounts.
+ // Accounts.
{
path: `/accounts`,
component: lazy(() => import('containers/Accounts/AccountsChart')),
@@ -14,6 +18,7 @@ export const getDashboardRoutes = () => [
hotkey: 'shift+a',
pageTitle: intl.get('accounts_chart'),
defaultSearchResource: RESOURCES_TYPES.ACCOUNT,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
// Accounting.
{
@@ -27,6 +32,7 @@ export const getDashboardRoutes = () => [
sidebarExpand: false,
backLink: true,
defaultSearchResource: RESOURCES_TYPES.MANUAL_JOURNAL,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/manual-journals/:id/edit`,
@@ -38,6 +44,7 @@ export const getDashboardRoutes = () => [
sidebarExpand: false,
backLink: true,
defaultSearchResource: RESOURCES_TYPES.MANUAL_JOURNAL,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/manual-journals`,
@@ -48,6 +55,7 @@ export const getDashboardRoutes = () => [
hotkey: 'shift+m',
pageTitle: intl.get('manual_journals'),
defaultSearchResource: RESOURCES_TYPES.MANUAL_JOURNAL,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/items/categories`,
@@ -57,6 +65,7 @@ export const getDashboardRoutes = () => [
breadcrumb: intl.get('categories'),
pageTitle: intl.get('category_list'),
defaultSearchResource: RESOURCES_TYPES.ITEM,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
// Items.
{
@@ -67,6 +76,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('edit_item'),
backLink: true,
defaultSearchResource: RESOURCES_TYPES.ITEM,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/items/new?duplicate=/:id`,
@@ -75,6 +85,7 @@ export const getDashboardRoutes = () => [
}),
breadcrumb: intl.get('duplicate_item'),
defaultSearchResource: RESOURCES_TYPES.ITEM,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/items/new`,
@@ -85,6 +96,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('new_item'),
backLink: true,
defaultSearchResource: RESOURCES_TYPES.ITEM,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/items`,
@@ -93,6 +105,7 @@ export const getDashboardRoutes = () => [
hotkey: 'shift+w',
pageTitle: intl.get('items_list'),
defaultSearchResource: RESOURCES_TYPES.ITEM,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
// Inventory adjustments.
@@ -104,6 +117,7 @@ export const getDashboardRoutes = () => [
breadcrumb: intl.get('inventory_adjustments'),
pageTitle: intl.get('inventory_adjustment_list'),
defaultSearchResource: RESOURCES_TYPES.ITEM,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
// Financial Reports.
@@ -119,6 +133,7 @@ export const getDashboardRoutes = () => [
backLink: true,
sidebarExpand: false,
defaultSearchResource: RESOURCES_TYPES.INVENTORY_ADJUSTMENT,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/financial-reports/balance-sheet`,
@@ -131,6 +146,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('balance_sheet'),
backLink: true,
sidebarExpand: false,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/financial-reports/trial-balance-sheet`,
@@ -145,6 +161,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('trial_balance_sheet'),
backLink: true,
sidebarExpand: false,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/financial-reports/profit-loss-sheet`,
@@ -157,6 +174,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('profit_loss_sheet'),
backLink: true,
sidebarExpand: false,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: '/financial-reports/receivable-aging-summary',
@@ -168,6 +186,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('receivable_aging_summary'),
backLink: true,
sidebarExpand: false,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: '/financial-reports/payable-aging-summary',
@@ -179,6 +198,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('payable_aging_summary'),
backLink: true,
sidebarExpand: false,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/financial-reports/journal-sheet`,
@@ -191,6 +211,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('journal_sheet'),
sidebarExpand: false,
backLink: true,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/financial-reports/purchases-by-items`,
@@ -204,6 +225,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('purchases_by_items'),
backLink: true,
sidebarExpand: false,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/financial-reports/sales-by-items`,
@@ -217,6 +239,7 @@ export const getDashboardRoutes = () => [
),
backLink: true,
sidebarExpand: false,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/financial-reports/inventory-valuation`,
@@ -230,6 +253,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('inventory_valuation'),
backLink: true,
sidebarExpand: false,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/financial-reports/customers-balance-summary`,
@@ -243,6 +267,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('customers_balance_summary'),
backLink: true,
sidebarExpand: false,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/financial-reports/vendors-balance-summary`,
@@ -256,6 +281,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('vendors_balance_summary'),
backLink: true,
sidebarExpand: false,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/financial-reports/transactions-by-customers`,
@@ -269,6 +295,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('customers_transactions'),
backLink: true,
sidebarExpand: false,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/financial-reports/transactions-by-vendors`,
@@ -282,6 +309,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('vendors_transactions'),
backLink: true,
sidebarExpand: false,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/financial-reports/cash-flow`,
@@ -295,6 +323,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('cash_flow_statement'),
backLink: true,
sidebarExpand: false,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/financial-reports/inventory-item-details`,
@@ -308,6 +337,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('inventory_item_details'),
backLink: true,
sidebarExpand: false,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: '/financial-reports',
@@ -316,6 +346,7 @@ export const getDashboardRoutes = () => [
),
breadcrumb: intl.get('financial_reports'),
pageTitle: intl.get('all_financial_reports'),
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
// Exchange Rates
{
@@ -323,6 +354,7 @@ export const getDashboardRoutes = () => [
component: lazy(() => import('containers/ExchangeRates/ExchangeRatesList')),
breadcrumb: intl.get('exchange_rates_list'),
pageTitle: intl.get('exchange_rates_list'),
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
// Expenses.
{
@@ -336,6 +368,7 @@ export const getDashboardRoutes = () => [
sidebarExpand: false,
backLink: true,
defaultSearchResource: RESOURCES_TYPES.EXPENSE,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/expenses/:id/edit`,
@@ -347,6 +380,7 @@ export const getDashboardRoutes = () => [
sidebarExpand: false,
backLink: true,
defaultSearchResource: RESOURCES_TYPES.EXPENSE,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/expenses`,
@@ -357,6 +391,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('expenses_list'),
hotkey: 'shift+x',
defaultSearchResource: RESOURCES_TYPES.EXPENSE,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
// Customers
@@ -370,6 +405,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('edit_customer'),
backLink: true,
defaultSearchResource: RESOURCES_TYPES.CUSTOMER,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/customers/new`,
@@ -382,6 +418,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('new_customer'),
backLink: true,
defaultSearchResource: RESOURCES_TYPES.CUSTOMER,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/customers`,
@@ -392,6 +429,7 @@ export const getDashboardRoutes = () => [
hotkey: 'shift+c',
pageTitle: intl.get('customers_list'),
defaultSearchResource: RESOURCES_TYPES.CUSTOMER,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/customers/contact_duplicate=/:id`,
@@ -403,6 +441,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('new_customer'),
backLink: true,
defaultSearchResource: RESOURCES_TYPES.CUSTOMER,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
// Vendors
@@ -416,6 +455,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('edit_vendor'),
backLink: true,
defaultSearchResource: RESOURCES_TYPES.VENDOR,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/vendors/new`,
@@ -428,6 +468,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('new_vendor'),
backLink: true,
defaultSearchResource: RESOURCES_TYPES.VENDOR,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/vendors`,
@@ -438,6 +479,7 @@ export const getDashboardRoutes = () => [
hotkey: 'shift+v',
pageTitle: intl.get('vendors_list'),
defaultSearchResource: RESOURCES_TYPES.VENDOR,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/vendors/contact_duplicate=/:id`,
@@ -449,6 +491,7 @@ export const getDashboardRoutes = () => [
pageTitle: intl.get('new_vendor'),
backLink: true,
defaultSearchResource: RESOURCES_TYPES.VENDOR,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
// Estimates
@@ -463,6 +506,7 @@ export const getDashboardRoutes = () => [
backLink: true,
sidebarExpand: false,
defaultSearchResource: RESOURCES_TYPES.ESTIMATE,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/invoices/new?from_estimate_id=/:id`,
@@ -475,6 +519,7 @@ export const getDashboardRoutes = () => [
backLink: true,
sidebarExpand: false,
defaultSearchResource: RESOURCES_TYPES.INVOICE,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/estimates/new`,
@@ -488,6 +533,7 @@ export const getDashboardRoutes = () => [
backLink: true,
sidebarExpand: false,
defaultSearchResource: RESOURCES_TYPES.ESTIMATE,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/estimates`,
@@ -499,6 +545,7 @@ export const getDashboardRoutes = () => [
hotkey: 'shift+e',
pageTitle: intl.get('estimates_list'),
defaultSearchResource: RESOURCES_TYPES.ESTIMATE,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
// Invoices.
@@ -513,6 +560,7 @@ export const getDashboardRoutes = () => [
sidebarExpand: false,
backLink: true,
defaultSearchResource: RESOURCES_TYPES.INVOICE,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/invoices/new`,
@@ -526,6 +574,7 @@ export const getDashboardRoutes = () => [
sidebarExpand: false,
backLink: true,
defaultSearchResource: RESOURCES_TYPES.INVOICE,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/invoices`,
@@ -536,6 +585,7 @@ export const getDashboardRoutes = () => [
hotkey: 'shift+i',
pageTitle: intl.get('invoices_list'),
defaultSearchResource: RESOURCES_TYPES.INVOICE,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
// Sales Receipts.
@@ -550,6 +600,7 @@ export const getDashboardRoutes = () => [
backLink: true,
sidebarExpand: false,
defaultSearchResource: RESOURCES_TYPES.RECEIPT,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/receipts/new`,
@@ -563,6 +614,7 @@ export const getDashboardRoutes = () => [
backLink: true,
sidebarExpand: false,
defaultSearchResource: RESOURCES_TYPES.RECEIPT,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/receipts`,
@@ -573,6 +625,7 @@ export const getDashboardRoutes = () => [
hotkey: 'shift+r',
pageTitle: intl.get('receipts_list'),
defaultSearchResource: RESOURCES_TYPES.RECEIPT,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
// Payment receives
@@ -589,6 +642,7 @@ export const getDashboardRoutes = () => [
backLink: true,
sidebarExpand: false,
defaultSearchResource: RESOURCES_TYPES.PAYMENT_RECEIVE,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/payment-receives/new`,
@@ -603,6 +657,7 @@ export const getDashboardRoutes = () => [
backLink: true,
sidebarExpand: false,
defaultSearchResource: RESOURCES_TYPES.PAYMENT_RECEIVE,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/payment-receives`,
@@ -614,6 +669,7 @@ export const getDashboardRoutes = () => [
breadcrumb: intl.get('payment_receives_list'),
pageTitle: intl.get('payment_receives_list'),
defaultSearchResource: RESOURCES_TYPES.PAYMENT_RECEIVE,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
// Bills
@@ -628,6 +684,7 @@ export const getDashboardRoutes = () => [
sidebarExpand: false,
backLink: true,
defaultSearchResource: RESOURCES_TYPES.BILL,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/bills/new`,
@@ -641,6 +698,7 @@ export const getDashboardRoutes = () => [
sidebarExpand: false,
backLink: true,
defaultSearchResource: RESOURCES_TYPES.BILL,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/bills`,
@@ -651,6 +709,7 @@ export const getDashboardRoutes = () => [
hotkey: 'shift+b',
pageTitle: intl.get('bills_list'),
defaultSearchResource: RESOURCES_TYPES.BILL,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
// Subscription billing.
@@ -658,6 +717,7 @@ export const getDashboardRoutes = () => [
path: `/billing`,
component: lazy(() => import('containers/Subscriptions/BillingForm')),
breadcrumb: intl.get('new_billing'),
+ subscriptionInactive: [SUBSCRIPTION_TYPE.MAIN]
},
// Payment modes.
{
@@ -673,6 +733,7 @@ export const getDashboardRoutes = () => [
sidebarExpand: false,
backLink: true,
defaultSearchResource: RESOURCES_TYPES.PAYMENT_MADE,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/payment-mades/new`,
@@ -687,6 +748,7 @@ export const getDashboardRoutes = () => [
sidebarExpand: false,
backLink: true,
defaultSearchResource: RESOURCES_TYPES.PAYMENT_MADE,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
{
path: `/payment-mades`,
@@ -698,11 +760,13 @@ export const getDashboardRoutes = () => [
breadcrumb: intl.get('payment_made_list'),
pageTitle: intl.get('payment_made_list'),
defaultSearchResource: RESOURCES_TYPES.PAYMENT_MADE,
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
// Homepage
{
path: `/`,
component: lazy(() => import('containers/Homepage/Homepage')),
breadcrumb: intl.get('homepage'),
+ subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
];
diff --git a/client/src/store/plans/plans.reducer.js b/client/src/store/plans/plans.reducer.js
index 472b353f4..e127cfbcf 100644
--- a/client/src/store/plans/plans.reducer.js
+++ b/client/src/store/plans/plans.reducer.js
@@ -1,69 +1,95 @@
-import React from 'react';
import { createReducer } from '@reduxjs/toolkit';
import intl from 'react-intl-universal';
import t from 'store/types';
-const getSubscriptionPlans = () => [
- {
- name: intl.get('Starter'),
- slug: 'free',
- // slug: 'starter',
- description: [
- intl.get('Sale and purchase invoices.'),
- intl.get('Customers/vendors accounts.'),
- intl.get('Expenses tracking'),
- intl.get('Manual journals.'),
- intl.get('Financial reports.'),
- intl.get('For one user and accountant.'),
- ],
- price: {
- month: '100',
- year: '1,200',
- },
- currencyCode: 'LYD',
- },
- {
- name: intl.get('Essential'),
- slug: 'plus',
- description: [
- intl.get('All Capital Starter features.'),
- intl.get('Multi-currency.'),
- intl.get('Purchase and sell orders.'),
- intl.get('Inventory management.'),
- intl.get('Three users with your accountant.'),
- intl.get('Advanced financial reports.'),
- ],
- price: {
- month: '200',
- year: '2,400',
- },
- currencyCode: 'LYD',
- },
- {
- name: intl.get('Enterprise'),
- slug: 'enterprise',
- description: [
- intl.get('All Capital Essential features.'),
- intl.get('Track multi-branches and locations.'),
- intl.get('Projects accounting and timesheets.'),
- intl.get('Accounting dimensions.'),
- ],
- price: {
- month: '300',
- year: '3,400',
- },
- currencyCode: 'LYD',
- },
-];
const getSubscriptionPeriods = () => [
{
slug: 'month',
- label: intl.get('Monthly'),
+ label: intl.get('plan.monthly'),
},
{
slug: 'year',
- label: intl.get('Yearly'),
+ label: intl.get('plan.yearly'),
+ },
+];
+
+const getSubscriptionPlans = () => [
+ {
+ name: intl.get('plan.essential.title'),
+ slug: 'free',
+ description: [
+ intl.get('plan.feature.sale_purchase_invoice'),
+ intl.get('plan.feature.receivable_payable_accounts'),
+ intl.get('plan.feature.expenses_tracking'),
+ intl.get('plan.feature.manual_journal'),
+ intl.get('plan.feature.financial_reports'),
+ intl.get('plan.feature.one_user_with_accountant'),
+ ],
+ price: '100',
+ periods: [
+ {
+ slug: 'month',
+ label: intl.get('plan.monthly'),
+ price: '100'
+ },
+ {
+ slug: 'year',
+ label: intl.get('plan.yearly'),
+ price: '1,200',
+ },
+ ],
+ currencyCode: 'LYD',
+ },
+ {
+ name: intl.get('plan.professional.title'),
+ slug: 'plus',
+ description: [
+ intl.get('plan.feature.all_capital_essential'),
+ intl.get('plan.feature.multi_currency'),
+ intl.get('plan.feature.purchase_sell_orders'),
+ intl.get('plan.feature.multi_inventory_managment'),
+ intl.get('plan.feature.three_users'),
+ intl.get('plan.feature.advanced_financial_reports'),
+ ],
+ price: '200',
+ currencyCode: 'LYD',
+ periods: [
+ {
+ slug: 'month',
+ label: intl.get('plan.monthly'),
+ price: '200'
+ },
+ {
+ slug: 'year',
+ label: intl.get('plan.yearly'),
+ price: '1,200',
+ },
+ ],
+ },
+ {
+ name: intl.get('plan.plus.title'),
+ slug: 'enterprise',
+ description: [
+ intl.get('plan.feture.all_capital_professional_features'),
+ intl.get('plan.feature.tracking_multi_locations'),
+ intl.get('plan.feature.projects_accounting'),
+ intl.get('plan.feature.accounting_dimensions'),
+ ],
+ price: '300',
+ currencyCode: 'LYD',
+ periods: [
+ {
+ slug: 'month',
+ label: intl.get('plan.monthly'),
+ price: '300'
+ },
+ {
+ slug: 'year',
+ label: intl.get('plan.yearly'),
+ price: '1,200',
+ },
+ ],
},
];
diff --git a/client/src/store/plans/plans.selectors.js b/client/src/store/plans/plans.selectors.js
index c2ea94478..02568c1be 100644
--- a/client/src/store/plans/plans.selectors.js
+++ b/client/src/store/plans/plans.selectors.js
@@ -4,8 +4,6 @@ const plansSelector = (state) => state.plans.plans;
const planSelector = (state, props) => state.plans.plans
.find((plan) => plan.slug === props.planSlug);
-const plansPeriodsSelector = (state) => state.plans.periods;
-
// Retrieve manual jounral current page results.
export const getPlansSelector = () => createSelector(
plansSelector,
@@ -14,14 +12,6 @@ export const getPlansSelector = () => createSelector(
},
);
-// Retrieve manual jounral current page results.
-export const getPlansPeriodsSelector = () => createSelector(
- plansPeriodsSelector,
- (periods) => {
- return periods;
- },
-);
-
// Retrieve plan details.
export const getPlanSelector = () => createSelector(
planSelector,
diff --git a/client/src/store/subscription/subscription.selectors.js b/client/src/store/subscription/subscription.selectors.js
index eb59631db..47387a2a6 100644
--- a/client/src/store/subscription/subscription.selectors.js
+++ b/client/src/store/subscription/subscription.selectors.js
@@ -1,23 +1,45 @@
import { createSelector } from '@reduxjs/toolkit';
+import { includes } from 'lodash';
-const subscriptionSelector = (slug) => (state, props) => {
+const subscriptionSelector = (slug) => (state, props) => {
const subscriptions = Object.values(state.subscriptions.data);
- return subscriptions.find((subscription) => subscription.slug === slug);
+ return subscriptions.find(
+ (subscription) => subscription.slug === (slug || props.subscriptionType),
+ );
};
-export const isSubscriptionOnTrialFactory = (slug) => createSelector(
- subscriptionSelector(slug),
- (subscription) => !!subscription?.on_trial,
-);
+const subscriptionsSelector = (state, props) => {
+ const subscriptions = Object.values(state.subscriptions.data);
+ return subscriptions.filter(
+ (subscription) =>
+ includes(props.subscriptionTypes, subscription.slug) ||
+ !props.subscriptionTypes,
+ );
+};
-export const isSubscriptionActiveFactory = (slug) => createSelector(
- subscriptionSelector(slug),
- (subscription) => {
+export const isSubscriptionOnTrialFactory = (slug) =>
+ createSelector(
+ subscriptionSelector(slug),
+ (subscription) => !!subscription?.on_trial,
+ );
+
+export const isSubscriptionActiveFactory = (slug) =>
+ createSelector(subscriptionSelector(slug), (subscription) => {
return !!subscription?.active;
- }
-);
+ });
-export const isSubscriptionInactiveFactory = (slug) => createSelector(
- subscriptionSelector(slug),
- (subscription) => !!subscription?.inactive,
-);
\ No newline at end of file
+export const isSubscriptionInactiveFactory = (slug) =>
+ createSelector(
+ subscriptionSelector(slug),
+ (subscription) => !!subscription?.inactive,
+ );
+
+export const isSubscriptionsInactiveFactory = () =>
+ createSelector(subscriptionsSelector, (subscriptions) =>
+ subscriptions.some((subscription) => subscription?.inactive),
+ );
+
+export const isSubscriptionsActiveFactory = () =>
+ createSelector(subscriptionsSelector, (subscriptions) =>
+ subscriptions.some((subscription) => subscription?.active),
+ );
diff --git a/client/src/style/containers/Dashboard/Sidebar.scss b/client/src/style/containers/Dashboard/Sidebar.scss
index d9a8df52b..38e1be39e 100644
--- a/client/src/style/containers/Dashboard/Sidebar.scss
+++ b/client/src/style/containers/Dashboard/Sidebar.scss
@@ -24,7 +24,7 @@
}
}
- .ScrollbarsCustom-Content{
+ .ScrollbarsCustom-Content {
display: flex;
flex-direction: column;
height: 100%;
@@ -50,7 +50,7 @@
opacity: 0;
visibility: hidden;
- svg{
+ svg {
opacity: $sidebar-logo-opacity;
}
}
@@ -69,12 +69,14 @@
&:not([class*="bp3-intent-"]):not(.bp3-minimal) {
color: rgb(255, 255, 255);
}
+
&:hover,
&:focus,
&:active,
&.bp3-active {
background: transparent;
}
+
.bp3-button-text {
margin-right: 4px;
text-overflow: ellipsis;
@@ -82,13 +84,14 @@
white-space: nowrap;
display: block;
}
+
svg {
fill: rgba(255, 255, 255, 0.3);
}
}
.bp3-popover-wrapper,
- .bp3-popover-target{
+ .bp3-popover-target {
max-width: 100%;
display: inline-block;
}
@@ -104,20 +107,24 @@
.sidebar__head-logo {
transition: transform 0.05s ease-in-out;
}
+
+ .is-subscription-inactive:not(.sidebar--mini-sidebar) & {
+ opacity: 0.6;
+ }
}
&__scroll-wrapper {
height: 100%;
}
-
- &__version{
+
+ &__version {
margin-top: auto;
padding: 0 20px 20px;
font-size: 12px;
color: rgba(255, 255, 255, 0.6);
}
- &__inner{
+ &__inner {
height: 100%;
display: flex;
flex-direction: column;
@@ -170,7 +177,7 @@
font-weight: 500;
letter-spacing: 1px;
- html[lang^="ar"] &{
+ html[lang^="ar"] & {
font-size: 12px;
letter-spacing: 0;
}
@@ -188,6 +195,7 @@
padding-bottom: 6px;
padding-top: 6px;
}
+
.#{$ns}-menu-item {
padding: 8px 20px;
font-size: 15px;
@@ -242,11 +250,11 @@
opacity: 1;
visibility: visible;
}
- // Hide text of bigcapital logo.
- &-logo {
- }
- &-organization{
+ // Hide text of bigcapital logo.
+ &-logo {}
+
+ &-organization {
opacity: 0;
transition: opacity 0.3s ease-in-out;
}
@@ -263,7 +271,7 @@
transition: min-width 0.15s ease-in-out;
min-width: 50px;
- .ScrollbarsCustom-Scroller{
+ .ScrollbarsCustom-Scroller {
overflow: hidden !important;
}
@@ -274,14 +282,14 @@
opacity: 0;
transition-delay: 0s;
}
-
+
.sidebar__head-organization,
.sidebar__menu,
.sidebar__version {
opacity: 1;
}
- .ScrollbarsCustom-Scroller{
+ .ScrollbarsCustom-Scroller {
overflow: scroll !important;
}
}
@@ -326,12 +334,14 @@
}
}
}
-.menu--dashboard-organization{
+
+.menu--dashboard-organization {
padding: 10px;
+
.org-item {
display: flex;
align-items: center;
-
+
&__logo {
height: 40px;
width: 40px;
@@ -343,16 +353,16 @@
font-size: 16px;
color: #fff;
}
-
+
&__name {
margin-left: 12px;
font-weight: 600;
}
- &__divider{
+ &__divider {
margin: 4px 0;
height: 1px;
background: #ebebeb;
}
}
-}
+}
\ No newline at end of file
diff --git a/client/src/style/pages/Billing/BillingPage.scss b/client/src/style/pages/Billing/BillingPage.scss
index 7250ddaa8..be72d6ef8 100644
--- a/client/src/style/pages/Billing/BillingPage.scss
+++ b/client/src/style/pages/Billing/BillingPage.scss
@@ -2,7 +2,7 @@
.billing-page{
padding: 0 60px;
- margin-top: 20px;
+ margin-top: 40px;
max-width: 820px;
.bp3-tab-list{
diff --git a/client/src/style/pages/Dashboard/Dashboard.scss b/client/src/style/pages/Dashboard/Dashboard.scss
index bb550ce1f..628356ac0 100644
--- a/client/src/style/pages/Dashboard/Dashboard.scss
+++ b/client/src/style/pages/Dashboard/Dashboard.scss
@@ -95,6 +95,17 @@ $dashboard-views-bar-height: 44px;
}
}
}
+
+ &-subscription-msg{
+ display: flex;
+ flex-direction: row;
+ padding-right: 6px;
+ font-size: 12px;
+
+ span{
+ margin: auto;
+ }
+ }
}
&__breadcrumbs {
diff --git a/client/src/style/pages/Setup/Congrats.scss b/client/src/style/pages/Setup/Congrats.scss
index 844b6c1cf..d2aaef755 100644
--- a/client/src/style/pages/Setup/Congrats.scss
+++ b/client/src/style/pages/Setup/Congrats.scss
@@ -1,5 +1,5 @@
.setup-congrats {
- width: 600px;
+ width: 500px;
margin: 0 auto;
text-align: center;
padding-top: 80px;
@@ -15,7 +15,7 @@
margin-bottom: 12px;
}
.paragraph {
- font-size: 15px;
+ font-size: 16px;
opacity: 0.85;
margin-bottom: 14px;
}
diff --git a/client/src/style/pages/Setup/Organization.scss b/client/src/style/pages/Setup/Organization.scss
index 82defab18..b694ce993 100644
--- a/client/src/style/pages/Setup/Organization.scss
+++ b/client/src/style/pages/Setup/Organization.scss
@@ -19,7 +19,9 @@
form {
h3 {
- margin-bottom: 1rem;
+ color: #4e5764;
+ margin-bottom: 1.2rem;
+ font-weight: 500;
}
}
diff --git a/client/src/style/pages/Setup/SetupPage.scss b/client/src/style/pages/Setup/SetupPage.scss
index c0c6471f0..b512c537a 100644
--- a/client/src/style/pages/Setup/SetupPage.scss
+++ b/client/src/style/pages/Setup/SetupPage.scss
@@ -1,3 +1,5 @@
+@import "../../Base.scss";
+
.setup-page {
max-width: 1600px;
@@ -9,15 +11,21 @@
&:before {
content: '';
display: block;
- width: 30%;
+ width: 100%;
height: 1px;
- min-width: 300px;
max-width: 350px;
+ min-width: 350px;
+
+ @media only screen and (max-width: 1200px) {
+ min-width: 300px;
+ max-width: 350px;
+ }
}
h1 {
font-size: 22px;
}
+
h1,
h3 {
font-weight: 500;
@@ -36,11 +44,14 @@
overflow: auto;
z-index: 1;
height: 100%;
- width: 30%;
+ width: 100%;
left: 0;
top: 0;
- max-width: 350px;
- min-width: 300px;
+ width: 350px;
+
+ @media only screen and (max-width: 1200px) {
+ width: 300px;
+ }
.content {
display: flex;
@@ -76,7 +87,7 @@
font-size: 16px;
opacity: 0.75;
- span > a {
+ span>a {
text-decoration: underline;
color: #ffffff;
margin-top: 6px;
@@ -101,7 +112,8 @@
opacity: 0.75;
padding-bottom: 5px;
border-bottom: 1px solid rgba(255, 255, 255, 0.15);
- p > span {
+
+ p>span {
unicode-bidi: plaintext;
}
}
@@ -110,7 +122,7 @@
text-align: left;
opacity: 0.55;
- > div {
+ >div {
font-size: 13px;
margin-right: 15px;
display: inline;
@@ -133,9 +145,11 @@
margin: 0 auto;
padding: 50px 0 0;
}
+
ul {
display: flex;
}
+
li {
position: relative;
list-style-type: none;
@@ -155,6 +169,7 @@
border-radius: 50%;
background-color: #75859c;
}
+
&::after {
width: 100%;
height: 2px;
@@ -165,24 +180,29 @@
left: -50%;
z-index: -1;
}
+
&:first-child::after {
display: none;
}
+
&.is-active {
text-decoration: underline;
&::before {
background-color: #75859c;
}
- ~ li {
+
+ ~li {
+
&:before,
&:after {
background: #e0e0e0;
}
}
+
p.wizard-info {
color: #004dd0;
}
}
}
-}
+}
\ No newline at end of file