diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..05e5a39 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,485 @@ +root = true + +[*] +charset = utf-8 +end_of_line = crlf +indent_size = 4 +indent_style = space +insert_final_newline = false +max_line_length = 120 +tab_width = 4 +ij_continuation_indent_size = 4 +ij_formatter_off_tag = @formatter:off +ij_formatter_on_tag = @formatter:on +ij_formatter_tags_enabled = true +ij_smart_tabs = false +ij_visual_guides = none +ij_wrap_on_typing = false + +[*.css] +ij_css_align_closing_brace_with_properties = false +ij_css_blank_lines_around_nested_selector = 1 +ij_css_blank_lines_between_blocks = 1 +ij_css_block_comment_add_space = false +ij_css_brace_placement = end_of_line +ij_css_enforce_quotes_on_format = false +ij_css_hex_color_long_format = false +ij_css_hex_color_lower_case = false +ij_css_hex_color_short_format = false +ij_css_hex_color_upper_case = false +ij_css_keep_blank_lines_in_code = 2 +ij_css_keep_indents_on_empty_lines = false +ij_css_keep_single_line_blocks = false +ij_css_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow +ij_css_space_after_colon = true +ij_css_space_before_opening_brace = true +ij_css_use_double_quotes = true +ij_css_value_alignment = do_not_align + +[*.sass] +indent_size = 2 +ij_sass_align_closing_brace_with_properties = false +ij_sass_blank_lines_around_nested_selector = 1 +ij_sass_blank_lines_between_blocks = 1 +ij_sass_brace_placement = 0 +ij_sass_enforce_quotes_on_format = false +ij_sass_hex_color_long_format = false +ij_sass_hex_color_lower_case = false +ij_sass_hex_color_short_format = false +ij_sass_hex_color_upper_case = false +ij_sass_keep_blank_lines_in_code = 2 +ij_sass_keep_indents_on_empty_lines = false +ij_sass_keep_single_line_blocks = false +ij_sass_line_comment_add_space = false +ij_sass_line_comment_at_first_column = false +ij_sass_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow +ij_sass_space_after_colon = true +ij_sass_space_before_opening_brace = true +ij_sass_use_double_quotes = true +ij_sass_value_alignment = 0 + +[*.scss] +indent_size = 2 +ij_scss_align_closing_brace_with_properties = false +ij_scss_blank_lines_around_nested_selector = 1 +ij_scss_blank_lines_between_blocks = 1 +ij_scss_block_comment_add_space = false +ij_scss_brace_placement = 0 +ij_scss_enforce_quotes_on_format = false +ij_scss_hex_color_long_format = false +ij_scss_hex_color_lower_case = false +ij_scss_hex_color_short_format = false +ij_scss_hex_color_upper_case = false +ij_scss_keep_blank_lines_in_code = 2 +ij_scss_keep_indents_on_empty_lines = false +ij_scss_keep_single_line_blocks = false +ij_scss_line_comment_add_space = false +ij_scss_line_comment_at_first_column = false +ij_scss_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow +ij_scss_space_after_colon = true +ij_scss_space_before_opening_brace = true +ij_scss_use_double_quotes = true +ij_scss_value_alignment = 0 + +[{*.ats,*.cts,*.mts,*.ts}] +ij_continuation_indent_size = 4 +ij_typescript_align_imports = false +ij_typescript_align_multiline_array_initializer_expression = false +ij_typescript_align_multiline_binary_operation = false +ij_typescript_align_multiline_chained_methods = false +ij_typescript_align_multiline_extends_list = false +ij_typescript_align_multiline_for = true +ij_typescript_align_multiline_parameters = true +ij_typescript_align_multiline_parameters_in_calls = false +ij_typescript_align_multiline_ternary_operation = false +ij_typescript_align_object_properties = 0 +ij_typescript_align_union_types = false +ij_typescript_align_var_statements = 0 +ij_typescript_array_initializer_new_line_after_left_brace = false +ij_typescript_array_initializer_right_brace_on_new_line = false +ij_typescript_array_initializer_wrap = off +ij_typescript_assignment_wrap = off +ij_typescript_binary_operation_sign_on_next_line = false +ij_typescript_binary_operation_wrap = off +ij_typescript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/** +ij_typescript_blank_lines_after_imports = 1 +ij_typescript_blank_lines_around_class = 1 +ij_typescript_blank_lines_around_field = 0 +ij_typescript_blank_lines_around_field_in_interface = 0 +ij_typescript_blank_lines_around_function = 1 +ij_typescript_blank_lines_around_method = 1 +ij_typescript_blank_lines_around_method_in_interface = 1 +ij_typescript_block_brace_style = end_of_line +ij_typescript_block_comment_add_space = false +ij_typescript_block_comment_at_first_column = true +ij_typescript_call_parameters_new_line_after_left_paren = false +ij_typescript_call_parameters_right_paren_on_new_line = false +ij_typescript_call_parameters_wrap = off +ij_typescript_catch_on_new_line = false +ij_typescript_chained_call_dot_on_new_line = true +ij_typescript_class_brace_style = end_of_line +ij_typescript_comma_on_new_line = false +ij_typescript_do_while_brace_force = never +ij_typescript_else_on_new_line = false +ij_typescript_enforce_trailing_comma = keep +ij_typescript_enum_constants_wrap = on_every_item +ij_typescript_extends_keyword_wrap = off +ij_typescript_extends_list_wrap = off +ij_typescript_field_prefix = _ +ij_typescript_file_name_style = relaxed +ij_typescript_finally_on_new_line = false +ij_typescript_for_brace_force = never +ij_typescript_for_statement_new_line_after_left_paren = false +ij_typescript_for_statement_right_paren_on_new_line = false +ij_typescript_for_statement_wrap = off +ij_typescript_force_quote_style = false +ij_typescript_force_semicolon_style = false +ij_typescript_function_expression_brace_style = end_of_line +ij_typescript_if_brace_force = never +ij_typescript_import_merge_members = global +ij_typescript_import_prefer_absolute_path = global +ij_typescript_import_sort_members = true +ij_typescript_import_sort_module_name = false +ij_typescript_import_use_node_resolution = true +ij_typescript_imports_wrap = on_every_item +ij_typescript_indent_case_from_switch = true +ij_typescript_indent_chained_calls = true +ij_typescript_indent_package_children = 0 +ij_typescript_jsdoc_include_types = false +ij_typescript_jsx_attribute_value = braces +ij_typescript_keep_blank_lines_in_code = 2 +ij_typescript_keep_first_column_comment = true +ij_typescript_keep_indents_on_empty_lines = false +ij_typescript_keep_line_breaks = true +ij_typescript_keep_simple_blocks_in_one_line = false +ij_typescript_keep_simple_methods_in_one_line = false +ij_typescript_line_comment_add_space = true +ij_typescript_line_comment_at_first_column = false +ij_typescript_method_brace_style = end_of_line +ij_typescript_method_call_chain_wrap = off +ij_typescript_method_parameters_new_line_after_left_paren = false +ij_typescript_method_parameters_right_paren_on_new_line = false +ij_typescript_method_parameters_wrap = off +ij_typescript_object_literal_wrap = on_every_item +ij_typescript_object_types_wrap = on_every_item +ij_typescript_parentheses_expression_new_line_after_left_paren = false +ij_typescript_parentheses_expression_right_paren_on_new_line = false +ij_typescript_place_assignment_sign_on_next_line = false +ij_typescript_prefer_as_type_cast = false +ij_typescript_prefer_explicit_types_function_expression_returns = false +ij_typescript_prefer_explicit_types_function_returns = false +ij_typescript_prefer_explicit_types_vars_fields = false +ij_typescript_prefer_parameters_wrap = false +ij_typescript_reformat_c_style_comments = false +ij_typescript_space_after_colon = true +ij_typescript_space_after_comma = true +ij_typescript_space_after_dots_in_rest_parameter = false +ij_typescript_space_after_generator_mult = true +ij_typescript_space_after_property_colon = true +ij_typescript_space_after_quest = true +ij_typescript_space_after_type_colon = true +ij_typescript_space_after_unary_not = false +ij_typescript_space_before_async_arrow_lparen = true +ij_typescript_space_before_catch_keyword = true +ij_typescript_space_before_catch_left_brace = true +ij_typescript_space_before_catch_parentheses = true +ij_typescript_space_before_class_lbrace = true +ij_typescript_space_before_class_left_brace = true +ij_typescript_space_before_colon = true +ij_typescript_space_before_comma = false +ij_typescript_space_before_do_left_brace = true +ij_typescript_space_before_else_keyword = true +ij_typescript_space_before_else_left_brace = true +ij_typescript_space_before_finally_keyword = true +ij_typescript_space_before_finally_left_brace = true +ij_typescript_space_before_for_left_brace = true +ij_typescript_space_before_for_parentheses = true +ij_typescript_space_before_for_semicolon = false +ij_typescript_space_before_function_left_parenth = true +ij_typescript_space_before_generator_mult = false +ij_typescript_space_before_if_left_brace = true +ij_typescript_space_before_if_parentheses = true +ij_typescript_space_before_method_call_parentheses = false +ij_typescript_space_before_method_left_brace = true +ij_typescript_space_before_method_parentheses = false +ij_typescript_space_before_property_colon = false +ij_typescript_space_before_quest = true +ij_typescript_space_before_switch_left_brace = true +ij_typescript_space_before_switch_parentheses = true +ij_typescript_space_before_try_left_brace = true +ij_typescript_space_before_type_colon = false +ij_typescript_space_before_unary_not = false +ij_typescript_space_before_while_keyword = true +ij_typescript_space_before_while_left_brace = true +ij_typescript_space_before_while_parentheses = true +ij_typescript_spaces_around_additive_operators = true +ij_typescript_spaces_around_arrow_function_operator = true +ij_typescript_spaces_around_assignment_operators = true +ij_typescript_spaces_around_bitwise_operators = true +ij_typescript_spaces_around_equality_operators = true +ij_typescript_spaces_around_logical_operators = true +ij_typescript_spaces_around_multiplicative_operators = true +ij_typescript_spaces_around_relational_operators = true +ij_typescript_spaces_around_shift_operators = true +ij_typescript_spaces_around_unary_operator = false +ij_typescript_spaces_within_array_initializer_brackets = false +ij_typescript_spaces_within_brackets = false +ij_typescript_spaces_within_catch_parentheses = false +ij_typescript_spaces_within_for_parentheses = false +ij_typescript_spaces_within_if_parentheses = false +ij_typescript_spaces_within_imports = false +ij_typescript_spaces_within_interpolation_expressions = false +ij_typescript_spaces_within_method_call_parentheses = false +ij_typescript_spaces_within_method_parentheses = false +ij_typescript_spaces_within_object_literal_braces = false +ij_typescript_spaces_within_object_type_braces = true +ij_typescript_spaces_within_parentheses = false +ij_typescript_spaces_within_switch_parentheses = false +ij_typescript_spaces_within_type_assertion = false +ij_typescript_spaces_within_union_types = true +ij_typescript_spaces_within_while_parentheses = false +ij_typescript_special_else_if_treatment = true +ij_typescript_ternary_operation_signs_on_next_line = false +ij_typescript_ternary_operation_wrap = off +ij_typescript_union_types_wrap = on_every_item +ij_typescript_use_chained_calls_group_indents = false +ij_typescript_use_double_quotes = true +ij_typescript_use_explicit_js_extension = auto +ij_typescript_use_path_mapping = always +ij_typescript_use_public_modifier = false +ij_typescript_use_semicolon_after_statement = true +ij_typescript_var_declaration_wrap = normal +ij_typescript_while_brace_force = never +ij_typescript_while_on_new_line = false +ij_typescript_wrap_comments = false + +[{*.cjs,*.js}] +ij_continuation_indent_size = 4 +ij_javascript_align_imports = false +ij_javascript_align_multiline_array_initializer_expression = false +ij_javascript_align_multiline_binary_operation = false +ij_javascript_align_multiline_chained_methods = false +ij_javascript_align_multiline_extends_list = false +ij_javascript_align_multiline_for = true +ij_javascript_align_multiline_parameters = true +ij_javascript_align_multiline_parameters_in_calls = false +ij_javascript_align_multiline_ternary_operation = false +ij_javascript_align_object_properties = 0 +ij_javascript_align_union_types = false +ij_javascript_align_var_statements = 0 +ij_javascript_array_initializer_new_line_after_left_brace = false +ij_javascript_array_initializer_right_brace_on_new_line = false +ij_javascript_array_initializer_wrap = off +ij_javascript_assignment_wrap = off +ij_javascript_binary_operation_sign_on_next_line = false +ij_javascript_binary_operation_wrap = off +ij_javascript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/** +ij_javascript_blank_lines_after_imports = 1 +ij_javascript_blank_lines_around_class = 1 +ij_javascript_blank_lines_around_field = 0 +ij_javascript_blank_lines_around_function = 1 +ij_javascript_blank_lines_around_method = 1 +ij_javascript_block_brace_style = end_of_line +ij_javascript_block_comment_add_space = false +ij_javascript_block_comment_at_first_column = true +ij_javascript_call_parameters_new_line_after_left_paren = false +ij_javascript_call_parameters_right_paren_on_new_line = false +ij_javascript_call_parameters_wrap = off +ij_javascript_catch_on_new_line = false +ij_javascript_chained_call_dot_on_new_line = true +ij_javascript_class_brace_style = end_of_line +ij_javascript_comma_on_new_line = false +ij_javascript_do_while_brace_force = never +ij_javascript_else_on_new_line = false +ij_javascript_enforce_trailing_comma = keep +ij_javascript_extends_keyword_wrap = off +ij_javascript_extends_list_wrap = off +ij_javascript_field_prefix = _ +ij_javascript_file_name_style = relaxed +ij_javascript_finally_on_new_line = false +ij_javascript_for_brace_force = never +ij_javascript_for_statement_new_line_after_left_paren = false +ij_javascript_for_statement_right_paren_on_new_line = false +ij_javascript_for_statement_wrap = off +ij_javascript_force_quote_style = false +ij_javascript_force_semicolon_style = false +ij_javascript_function_expression_brace_style = end_of_line +ij_javascript_if_brace_force = never +ij_javascript_import_merge_members = global +ij_javascript_import_prefer_absolute_path = global +ij_javascript_import_sort_members = true +ij_javascript_import_sort_module_name = false +ij_javascript_import_use_node_resolution = true +ij_javascript_imports_wrap = on_every_item +ij_javascript_indent_case_from_switch = true +ij_javascript_indent_chained_calls = true +ij_javascript_indent_package_children = 0 +ij_javascript_jsx_attribute_value = braces +ij_javascript_keep_blank_lines_in_code = 2 +ij_javascript_keep_first_column_comment = true +ij_javascript_keep_indents_on_empty_lines = false +ij_javascript_keep_line_breaks = true +ij_javascript_keep_simple_blocks_in_one_line = false +ij_javascript_keep_simple_methods_in_one_line = false +ij_javascript_line_comment_add_space = true +ij_javascript_line_comment_at_first_column = false +ij_javascript_method_brace_style = end_of_line +ij_javascript_method_call_chain_wrap = off +ij_javascript_method_parameters_new_line_after_left_paren = false +ij_javascript_method_parameters_right_paren_on_new_line = false +ij_javascript_method_parameters_wrap = off +ij_javascript_object_literal_wrap = on_every_item +ij_javascript_object_types_wrap = on_every_item +ij_javascript_parentheses_expression_new_line_after_left_paren = false +ij_javascript_parentheses_expression_right_paren_on_new_line = false +ij_javascript_place_assignment_sign_on_next_line = false +ij_javascript_prefer_as_type_cast = false +ij_javascript_prefer_explicit_types_function_expression_returns = false +ij_javascript_prefer_explicit_types_function_returns = false +ij_javascript_prefer_explicit_types_vars_fields = false +ij_javascript_prefer_parameters_wrap = false +ij_javascript_reformat_c_style_comments = false +ij_javascript_space_after_colon = true +ij_javascript_space_after_comma = true +ij_javascript_space_after_dots_in_rest_parameter = false +ij_javascript_space_after_generator_mult = true +ij_javascript_space_after_property_colon = true +ij_javascript_space_after_quest = true +ij_javascript_space_after_type_colon = true +ij_javascript_space_after_unary_not = false +ij_javascript_space_before_async_arrow_lparen = true +ij_javascript_space_before_catch_keyword = true +ij_javascript_space_before_catch_left_brace = true +ij_javascript_space_before_catch_parentheses = true +ij_javascript_space_before_class_lbrace = true +ij_javascript_space_before_class_left_brace = true +ij_javascript_space_before_colon = true +ij_javascript_space_before_comma = false +ij_javascript_space_before_do_left_brace = true +ij_javascript_space_before_else_keyword = true +ij_javascript_space_before_else_left_brace = true +ij_javascript_space_before_finally_keyword = true +ij_javascript_space_before_finally_left_brace = true +ij_javascript_space_before_for_left_brace = true +ij_javascript_space_before_for_parentheses = true +ij_javascript_space_before_for_semicolon = false +ij_javascript_space_before_function_left_parenth = true +ij_javascript_space_before_generator_mult = false +ij_javascript_space_before_if_left_brace = true +ij_javascript_space_before_if_parentheses = true +ij_javascript_space_before_method_call_parentheses = false +ij_javascript_space_before_method_left_brace = true +ij_javascript_space_before_method_parentheses = false +ij_javascript_space_before_property_colon = false +ij_javascript_space_before_quest = true +ij_javascript_space_before_switch_left_brace = true +ij_javascript_space_before_switch_parentheses = true +ij_javascript_space_before_try_left_brace = true +ij_javascript_space_before_type_colon = false +ij_javascript_space_before_unary_not = false +ij_javascript_space_before_while_keyword = true +ij_javascript_space_before_while_left_brace = true +ij_javascript_space_before_while_parentheses = true +ij_javascript_spaces_around_additive_operators = true +ij_javascript_spaces_around_arrow_function_operator = true +ij_javascript_spaces_around_assignment_operators = true +ij_javascript_spaces_around_bitwise_operators = true +ij_javascript_spaces_around_equality_operators = true +ij_javascript_spaces_around_logical_operators = true +ij_javascript_spaces_around_multiplicative_operators = true +ij_javascript_spaces_around_relational_operators = true +ij_javascript_spaces_around_shift_operators = true +ij_javascript_spaces_around_unary_operator = false +ij_javascript_spaces_within_array_initializer_brackets = false +ij_javascript_spaces_within_brackets = false +ij_javascript_spaces_within_catch_parentheses = false +ij_javascript_spaces_within_for_parentheses = false +ij_javascript_spaces_within_if_parentheses = false +ij_javascript_spaces_within_imports = false +ij_javascript_spaces_within_interpolation_expressions = false +ij_javascript_spaces_within_method_call_parentheses = false +ij_javascript_spaces_within_method_parentheses = false +ij_javascript_spaces_within_object_literal_braces = false +ij_javascript_spaces_within_object_type_braces = true +ij_javascript_spaces_within_parentheses = false +ij_javascript_spaces_within_switch_parentheses = false +ij_javascript_spaces_within_type_assertion = false +ij_javascript_spaces_within_union_types = true +ij_javascript_spaces_within_while_parentheses = false +ij_javascript_special_else_if_treatment = true +ij_javascript_ternary_operation_signs_on_next_line = false +ij_javascript_ternary_operation_wrap = off +ij_javascript_union_types_wrap = on_every_item +ij_javascript_use_chained_calls_group_indents = false +ij_javascript_use_double_quotes = true +ij_javascript_use_explicit_js_extension = auto +ij_javascript_use_path_mapping = always +ij_javascript_use_public_modifier = false +ij_javascript_use_semicolon_after_statement = true +ij_javascript_var_declaration_wrap = normal +ij_javascript_while_brace_force = never +ij_javascript_while_on_new_line = false +ij_javascript_wrap_comments = false + +[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.prettierrc,.stylelintrc,bowerrc,jest.config}] +indent_size = 2 +ij_json_array_wrapping = split_into_lines +ij_json_keep_blank_lines_in_code = 0 +ij_json_keep_indents_on_empty_lines = false +ij_json_keep_line_breaks = true +ij_json_keep_trailing_comma = false +ij_json_object_wrapping = split_into_lines +ij_json_property_alignment = do_not_align +ij_json_space_after_colon = true +ij_json_space_after_comma = true +ij_json_space_before_colon = false +ij_json_space_before_comma = false +ij_json_spaces_within_braces = false +ij_json_spaces_within_brackets = false +ij_json_wrap_long_lines = false + +[{*.htm,*.html,*.ng,*.sht,*.shtm,*.shtml}] +ij_html_add_new_line_before_tags = body, div, p, form, h1, h2, h3 +ij_html_align_attributes = true +ij_html_align_text = false +ij_html_attribute_wrap = normal +ij_html_block_comment_add_space = false +ij_html_block_comment_at_first_column = true +ij_html_do_not_align_children_of_min_lines = 0 +ij_html_do_not_break_if_inline_tags = title, h1, h2, h3, h4, h5, h6, p +ij_html_do_not_indent_children_of_tags = html, body, thead, tbody, tfoot +ij_html_enforce_quotes = false +ij_html_inline_tags = a, abbr, acronym, b, basefont, bdo, big, br, cite, cite, code, dfn, em, font, i, img, input, kbd, label, q, s, samp, select, small, span, strike, strong, sub, sup, textarea, tt, u, var +ij_html_keep_blank_lines = 2 +ij_html_keep_indents_on_empty_lines = false +ij_html_keep_line_breaks = true +ij_html_keep_line_breaks_in_text = true +ij_html_keep_whitespaces = false +ij_html_keep_whitespaces_inside = span, pre, textarea +ij_html_line_comment_at_first_column = true +ij_html_new_line_after_last_attribute = never +ij_html_new_line_before_first_attribute = never +ij_html_quote_style = double +ij_html_remove_new_line_before_tags = br +ij_html_space_after_tag_name = false +ij_html_space_around_equality_in_attribute = false +ij_html_space_inside_empty_tag = false +ij_html_text_wrap = normal + +[{*.markdown,*.md}] +ij_markdown_force_one_space_after_blockquote_symbol = true +ij_markdown_force_one_space_after_header_symbol = true +ij_markdown_force_one_space_after_list_bullet = true +ij_markdown_force_one_space_between_words = true +ij_markdown_format_tables = true +ij_markdown_insert_quote_arrows_on_wrap = true +ij_markdown_keep_indents_on_empty_lines = false +ij_markdown_keep_line_breaks_inside_text_blocks = true +ij_markdown_max_lines_around_block_elements = 1 +ij_markdown_max_lines_around_header = 1 +ij_markdown_max_lines_between_paragraphs = 1 +ij_markdown_min_lines_around_block_elements = 1 +ij_markdown_min_lines_around_header = 1 +ij_markdown_min_lines_between_paragraphs = 1 +ij_markdown_wrap_text_if_long = true +ij_markdown_wrap_text_inside_blockquotes = true diff --git a/.gitignore b/.gitignore index e9618a3..78b977c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ node_modules .next -.env.local \ No newline at end of file +.env.local +.idea +package-lock.json \ No newline at end of file diff --git a/README.md b/README.md index 500a317..20bc2ee 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,18 @@ # loan-facilities-user - - ## Getting started To make it easy for you to get started with GitLab, here's a list of recommended next steps. -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! +Already a pro? Just edit this README.md and make it your own. Want to make it +easy? [Use the template at the bottom](#editing-this-readme)! ## Add your files -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: +- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) + or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files +- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) + or push an existing Git repository with the following command: ``` cd existing_repo @@ -46,47 +47,82 @@ Use the built-in continuous integration in GitLab. # Editing this README -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template. +When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to +structure it however you want - this is just a starting point!). Thank you +to [makeareadme.com](https://www.makeareadme.com/) for this template. ## Suggestions for a good README -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. + +Every project is different, so consider which of these sections apply to yours. The sections used in the template are +suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long +is better than too short. If you think your README is too long, consider utilizing another form of documentation rather +than cutting out information. ## Name + Choose a self-explaining name for your project. ## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. + +Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be +unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your +project, this is a good place to list differentiating factors. ## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. + +On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the +project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. ## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. + +Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see +GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. ## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. + +Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. +However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing +specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a +specific context like a particular programming language version or operating system or has dependencies that have to be +installed manually, also add a Requirements subsection. ## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. + +Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of +usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably +include in the README. ## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. + +Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, +etc. ## Roadmap + If you have ideas for releases in the future, it is a good idea to list them in the README. ## Contributing + State if you are open to contributions and what your requirements are for accepting them. -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. +For people who want to make changes to your project, it's helpful to have some documentation on how to get started. +Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps +explicit. These instructions could also be useful to your future self. -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. +You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce +the likelihood that the changes inadvertently break something. Having instructions for running tests is especially +helpful if it requires external setup, such as starting a Selenium server for testing in a browser. ## Authors and acknowledgment + Show your appreciation to those who have contributed to the project. ## License + For open source projects, say how it is licensed. ## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. + +If you have run out of energy or time for your project, put a note at the top of the README saying that development has +slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or +owner, allowing your project to keep going. You can also make an explicit request for maintainers. diff --git a/example.env.local b/example.env.local index 2b26da5..554476c 100644 --- a/example.env.local +++ b/example.env.local @@ -1,8 +1,10 @@ NEXT_PUBLIC_API_NAME = "Loan Facilities Dashboard" +NEXT_PUBLIC_API_VERSION = "1.7.1" NEXT_PUBLIC_DEFAULT_LANGUAGE = "fa" NEXT_PUBLIC_DEFAULT_DIRECTION = "rtl" -NEXT_PUBLIC_API_URL = "http://Your IP:3000" +NEXT_PUBLIC_PRIMARY_MAIN = "#084070" +NEXT_PUBLIC_SECONDARY_MAIN = "#FF4E00" NEXT_PUBLIC_BASE_URL = "deploy api" diff --git a/jsconfig.json b/jsconfig.json index f6a30b1..fcd02aa 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -1,8 +1,12 @@ { "compilerOptions": { "paths": { - "@/*": ["./src/*"], - "&/*": ["./public/*"], + "@/*": [ + "./src/*" + ], + "&/*": [ + "./public/*" + ] } } } diff --git a/next.config.js b/next.config.js index 03fb527..db2124f 100644 --- a/next.config.js +++ b/next.config.js @@ -1,12 +1,15 @@ /** @type {import('next').NextConfig} */ const nextConfig = { - reactStrictMode: true, - i18n: { - defaultLocale: 'fa', - locales: ['fa'], - localeDetection: false, - }, + reactStrictMode: true, + images: { + domains: ['loan.witel.ir', /* other domains */], + }, + i18n: { + defaultLocale: 'fa', + locales: ['fa'], + localeDetection: false, + }, } module.exports = nextConfig diff --git a/package-lock.json b/package-lock.json index 2f1e600..5679aee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,9 +14,11 @@ "@mui/icons-material": "^5.11.16", "@mui/material": "^5.12.0", "axios": "^1.4.0", + "colord": "^2.9.3", "eslint": "8.36.0", "formik": "^2.2.9", "fs-extra": "^11.1.1", + "jalali-moment": "^3.3.11", "material-react-table": "^1.11.1", "moment": "^2.29.4", "next": "^13.3.0", @@ -1236,6 +1238,31 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -1431,6 +1458,25 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -1439,6 +1485,56 @@ "node": ">=8" } }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bl/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bl/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1459,6 +1555,29 @@ "node": ">=8" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/buffer-from": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.2.tgz", @@ -1526,6 +1645,11 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -1563,11 +1687,49 @@ "node": ">= 6" } }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", + "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "engines": { + "node": ">= 10" + } + }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "engines": { + "node": ">=0.8" + } + }, "node_modules/clsx": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", @@ -1592,6 +1754,11 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1603,6 +1770,14 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1722,6 +1897,17 @@ "node": ">=0.10.0" } }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", @@ -2402,6 +2588,19 @@ "node": ">=0.10.0" } }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2453,6 +2652,28 @@ "reusify": "^1.0.4" } }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -2894,6 +3115,36 @@ "html-tokenize": "bin/cmd.js" } }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -2944,6 +3195,31 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/inquirer": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", + "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/internal-slot": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", @@ -3121,6 +3397,14 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -3132,6 +3416,14 @@ "node": ">=0.10.0" } }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-map": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", @@ -3270,6 +3562,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-weakmap": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", @@ -3327,6 +3630,19 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "node_modules/jalali-moment": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/jalali-moment/-/jalali-moment-3.3.11.tgz", + "integrity": "sha512-tdSaRs9cjWjOIaWhcsGFZMhZQhfgok5J0TwqFpBIZPudZxxa6yjUPoLCOwuvbAtRpiZn7k/mvazAJh+vEN5suw==", + "dependencies": { + "commander": "^7.0.0", + "inquirer": "^8.0.0", + "moment": "^2.26.0" + }, + "bin": { + "jalalim": "cli.js" + } + }, "node_modules/js-sdsl": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", @@ -3464,6 +3780,21 @@ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -3554,6 +3885,14 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -3595,6 +3934,11 @@ "object-assign": "^4.1.0" } }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, "node_modules/nanoid": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", @@ -3855,6 +4199,20 @@ "wrappy": "1" } }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/open": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", @@ -3888,6 +4246,36 @@ "node": ">= 0.8.0" } }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -4218,6 +4606,18 @@ "node": ">=4" } }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -4241,6 +4641,14 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -4263,6 +4671,14 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -4282,6 +4698,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "node_modules/sass": { "version": "1.62.0", "resolved": "https://registry.npmjs.org/sass/-/sass-1.62.0.tgz", @@ -4354,6 +4775,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -4404,6 +4830,24 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, "node_modules/string.prototype.matchall": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", @@ -4617,6 +5061,17 @@ "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -4806,6 +5261,14 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dependencies": { + "defaults": "^1.0.3" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4879,6 +5342,19 @@ "node": ">=0.10.0" } }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -5728,6 +6204,21 @@ "uri-js": "^4.2.2" } }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "requires": { + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + } + } + }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -5877,11 +6368,51 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -5899,6 +6430,15 @@ "fill-range": "^7.0.1" } }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "buffer-from": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.2.tgz", @@ -5941,6 +6481,11 @@ "supports-color": "^7.1.0" } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -5966,11 +6511,34 @@ } } }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-spinners": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", + "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==" + }, + "cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==" + }, "client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==" + }, "clsx": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", @@ -5989,6 +6557,11 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -5997,6 +6570,11 @@ "delayed-stream": "~1.0.0" } }, + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -6093,6 +6671,14 @@ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==" }, + "defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "requires": { + "clone": "^1.0.2" + } + }, "define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", @@ -6626,6 +7212,16 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -6673,6 +7269,21 @@ "reusify": "^1.0.4" } }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "requires": { + "escape-string-regexp": "^1.0.5" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + } + } + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -6984,6 +7595,19 @@ "through2": "~0.4.1" } }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, "ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -7022,6 +7646,28 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "inquirer": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", + "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + } + }, "internal-slot": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", @@ -7150,6 +7796,11 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -7158,6 +7809,11 @@ "is-extglob": "^2.1.1" } }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==" + }, "is-map": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", @@ -7245,6 +7901,11 @@ "has-tostringtag": "^1.0.0" } }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" + }, "is-weakmap": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", @@ -7290,6 +7951,16 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "jalali-moment": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/jalali-moment/-/jalali-moment-3.3.11.tgz", + "integrity": "sha512-tdSaRs9cjWjOIaWhcsGFZMhZQhfgok5J0TwqFpBIZPudZxxa6yjUPoLCOwuvbAtRpiZn7k/mvazAJh+vEN5suw==", + "requires": { + "commander": "^7.0.0", + "inquirer": "^8.0.0", + "moment": "^2.26.0" + } + }, "js-sdsl": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", @@ -7403,6 +8074,15 @@ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -7460,6 +8140,11 @@ "mime-db": "1.52.0" } }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -7492,6 +8177,11 @@ "object-assign": "^4.1.0" } }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, "nanoid": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", @@ -7657,6 +8347,14 @@ "wrappy": "1" } }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, "open": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", @@ -7681,6 +8379,27 @@ "word-wrap": "^1.2.3" } }, + "ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "requires": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" + }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -7909,6 +8628,15 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -7922,6 +8650,11 @@ "glob": "^7.1.3" } }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" + }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -7930,6 +8663,14 @@ "queue-microtask": "^1.2.2" } }, + "rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "requires": { + "tslib": "^2.1.0" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -7946,6 +8687,11 @@ "is-regex": "^1.1.4" } }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "sass": { "version": "1.62.0", "resolved": "https://registry.npmjs.org/sass/-/sass-1.62.0.tgz", @@ -7997,6 +8743,11 @@ "object-inspect": "^1.9.0" } }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -8032,6 +8783,23 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + } + } + }, "string.prototype.matchall": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", @@ -8186,6 +8954,14 @@ "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -8319,6 +9095,14 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "requires": { + "defaults": "^1.0.3" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -8371,6 +9155,16 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index cbb68a7..9dc4a67 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "dev": "next dev", "build": "next build", "start": "next start", + "publish-3001": "next start -p 3001", "lint": "next lint" }, "dependencies": { @@ -15,9 +16,11 @@ "@mui/icons-material": "^5.11.16", "@mui/material": "^5.12.0", "axios": "^1.4.0", + "colord": "^2.9.3", "eslint": "8.36.0", "formik": "^2.2.9", "fs-extra": "^11.1.1", + "jalali-moment": "^3.3.11", "material-react-table": "^1.11.1", "moment": "^2.29.4", "next": "^13.3.0", diff --git a/public/fontiran.scss b/public/fontiran.scss index e263b42..86d585d 100644 --- a/public/fontiran.scss +++ b/public/fontiran.scss @@ -17,80 +17,153 @@ This set of fonts are used in this project under the license: (.....) * **/ @font-face { - font-family: IRANSans; - font-style: normal; - font-weight: 900; - src: url('./fonts/eot/IRANSansWeb_Black.eot'); - src: url('./fonts/eot/IRANSansWeb_Black.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ - url('./fonts/woff2/IRANSansWeb_Black.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ - url('./fonts/woff/IRANSansWeb_Black.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ - url('./fonts/ttf/IRANSansWeb_Black.ttf') format('truetype'); + font-family: IRANSansFaNum; + font-style: normal; + font-weight: 900; + src: url('./fonts/eot/IRANSansWeb(FaNum)_Black.eot'); + src: url('./fonts/eot/IRANSansWeb(FaNum)_Black.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('./fonts/woff2/IRANSansWeb(FaNum)_Black.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('./fonts/woff/IRANSansWeb(FaNum)_Black.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('./fonts/ttf/IRANSansWeb(FaNum)_Black.ttf') format('truetype'); } + @font-face { - font-family: IRANSans; - font-style: normal; - font-weight: bold; - src: url('./fonts/eot/IRANSansWeb_Bold.eot'); - src: url('./fonts/eot/IRANSansWeb_Bold.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ - url('./fonts/woff2/IRANSansWeb_Bold.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ - url('./fonts/woff/IRANSansWeb_Bold.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ - url('./fonts/ttf/IRANSansWeb_Bold.ttf') format('truetype'); + font-family: IRANSansFaNum; + font-style: normal; + font-weight: bold; + src: url('./fonts/eot/IRANSansWeb(FaNum)_Bold.eot'); + src: url('./fonts/eot/IRANSansWeb(FaNum)_Bold.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('./fonts/woff2/IRANSansWeb(FaNum)_Bold.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('./fonts/woff/IRANSansWeb(FaNum)_Bold.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('./fonts/ttf/IRANSansWeb(FaNum)_Bold.ttf') format('truetype'); } + @font-face { - font-family: IRANSans; - font-style: normal; - font-weight: 500; - src: url('./fonts/eot/IRANSansWeb_Medium.eot'); - src: url('./fonts/eot/IRANSansWeb_Medium.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ - url('./fonts/woff2/IRANSansWeb_Medium.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ - url('./fonts/woff/IRANSansWeb_Medium.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ - url('./fonts/ttf/IRANSansWeb_Medium.ttf') format('truetype'); + font-family: IRANSansFaNum; + font-style: normal; + font-weight: 500; + src: url('./fonts/eot/IRANSansWeb(FaNum)_Medium.eot'); + src: url('./fonts/eot/IRANSansWeb(FaNum)_Medium.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('./fonts/woff2/IRANSansWeb(FaNum)_Medium.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('./fonts/woff/IRANSansWeb(FaNum)_Medium.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('./fonts/ttf/IRANSansWeb(FaNum)_Medium.ttf') format('truetype'); } + @font-face { - font-family: IRANSans; - font-style: normal; - font-weight: 300; - src: url('./fonts/eot/IRANSansWeb_Light.eot'); - src: url('./fonts/eot/IRANSansWeb_Light.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ - url('./fonts/woff2/IRANSansWeb_Light.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ - url('./fonts/woff/IRANSansWeb_Light.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ - url('./fonts/ttf/IRANSansWeb_Light.ttf') format('truetype'); + font-family: IRANSansFaNum; + font-style: normal; + font-weight: 300; + src: url('./fonts/eot/IRANSansWeb(FaNum)_Light.eot'); + src: url('./fonts/eot/IRANSansWeb(FaNum)_Light.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('./fonts/woff2/IRANSansWeb(FaNum)_Light.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('./fonts/woff/IRANSansWeb(FaNum)_Light.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('./fonts/ttf/IRANSansWeb(FaNum)_Light.ttf') format('truetype'); } + @font-face { - font-family: IRANSans; - font-style: normal; - font-weight: 200; - src: url('./fonts/eot/IRANSansWeb_UltraLight.eot'); - src: url('./fonts/eot/IRANSansWeb_UltraLight.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ - url('./fonts/woff2/IRANSansWeb_UltraLight.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ - url('./fonts/woff/IRANSansWeb_UltraLight.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ - url('./fonts/ttf/IRANSansWeb_UltraLight.ttf') format('truetype'); + font-family: IRANSansFaNum; + font-style: normal; + font-weight: 200; + src: url('./fonts/eot/IRANSansWeb(FaNum)_UltraLight.eot'); + src: url('./fonts/eot/IRANSansWeb(FaNum)_UltraLight.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('./fonts/woff2/IRANSansWeb(FaNum)_UltraLight.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('./fonts/woff/IRANSansWeb(FaNum)_UltraLight.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('./fonts/ttf/IRANSansWeb(FaNum)_UltraLight.ttf') format('truetype'); } + @font-face { - font-family: IRANSans; - font-style: normal; - font-weight: normal; - src: url('./fonts/eot/IRANSansWeb.eot'); - src: url('./fonts/eot/IRANSansWeb.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ - url('./fonts/woff2/IRANSansWeb.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ - url('./fonts/woff/IRANSansWeb.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ - url('./fonts/ttf/IRANSansWeb.ttf') format('truetype'); + font-family: IRANSansFaNum; + font-style: normal; + font-weight: normal; + src: url('./fonts/eot/IRANSansWeb(FaNum).eot'); + src: url('./fonts/eot/IRANSansWeb(FaNum).eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('./fonts/woff2/IRANSansWeb(FaNum).woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('./fonts/woff/IRANSansWeb(FaNum).woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('./fonts/ttf/IRANSansWeb(FaNum).ttf') format('truetype'); } + @font-face { - font-family: Parastoo; - font-style: normal; - font-weight: normal; - src: url('./fonts/eot/Parastoo.eot'); - src: url('./fonts/eot/Parastoo.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ - url('./fonts/woff/Parastoo.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ - url('./fonts/ttf/Parastoo.ttf') format('truetype'); + font-family: IRANSans; + font-style: normal; + font-weight: 900; + src: url('./fonts/eot/IRANSansWeb_Black.eot'); + src: url('./fonts/eot/IRANSansWeb_Black.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('./fonts/woff2/IRANSansWeb_Black.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('./fonts/woff/IRANSansWeb_Black.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('./fonts/ttf/IRANSansWeb_Black.ttf') format('truetype'); } + @font-face { - font-family: Parastoo; - font-style: normal; - font-weight: bold; - src: url('./fonts/eot/Parastoo-Bold.eot'); - src: url('./fonts/eot/Parastoo-Bold.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ - url('./fonts/woff/Parastoo-Bold.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ - url('./fonts/ttf/Parastoo-Bold.ttf') format('truetype'); + font-family: IRANSans; + font-style: normal; + font-weight: bold; + src: url('./fonts/eot/IRANSansWeb_Bold.eot'); + src: url('./fonts/eot/IRANSansWeb_Bold.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('./fonts/woff2/IRANSansWeb_Bold.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('./fonts/woff/IRANSansWeb_Bold.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('./fonts/ttf/IRANSansWeb_Bold.ttf') format('truetype'); +} + +@font-face { + font-family: IRANSans; + font-style: normal; + font-weight: 500; + src: url('./fonts/eot/IRANSansWeb_Medium.eot'); + src: url('./fonts/eot/IRANSansWeb_Medium.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('./fonts/woff2/IRANSansWeb_Medium.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('./fonts/woff/IRANSansWeb_Medium.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('./fonts/ttf/IRANSansWeb_Medium.ttf') format('truetype'); +} + +@font-face { + font-family: IRANSans; + font-style: normal; + font-weight: 300; + src: url('./fonts/eot/IRANSansWeb_Light.eot'); + src: url('./fonts/eot/IRANSansWeb_Light.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('./fonts/woff2/IRANSansWeb_Light.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('./fonts/woff/IRANSansWeb_Light.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('./fonts/ttf/IRANSansWeb_Light.ttf') format('truetype'); +} + +@font-face { + font-family: IRANSans; + font-style: normal; + font-weight: 200; + src: url('./fonts/eot/IRANSansWeb_UltraLight.eot'); + src: url('./fonts/eot/IRANSansWeb_UltraLight.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('./fonts/woff2/IRANSansWeb_UltraLight.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('./fonts/woff/IRANSansWeb_UltraLight.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('./fonts/ttf/IRANSansWeb_UltraLight.ttf') format('truetype'); +} + +@font-face { + font-family: IRANSans; + font-style: normal; + font-weight: normal; + src: url('./fonts/eot/IRANSansWeb.eot'); + src: url('./fonts/eot/IRANSansWeb.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('./fonts/woff2/IRANSansWeb.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('./fonts/woff/IRANSansWeb.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('./fonts/ttf/IRANSansWeb.ttf') format('truetype'); +} + +@font-face { + font-family: Parastoo; + font-style: normal; + font-weight: normal; + src: url('./fonts/eot/Parastoo.eot'); + src: url('./fonts/eot/Parastoo.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('./fonts/woff/Parastoo.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('./fonts/ttf/Parastoo.ttf') format('truetype'); +} + +@font-face { + font-family: Parastoo; + font-style: normal; + font-weight: bold; + src: url('./fonts/eot/Parastoo-Bold.eot'); + src: url('./fonts/eot/Parastoo-Bold.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('./fonts/woff/Parastoo-Bold.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('./fonts/ttf/Parastoo-Bold.ttf') format('truetype'); } diff --git a/public/fonts/eot/IRANSansWeb(FaNum).eot b/public/fonts/eot/IRANSansWeb(FaNum).eot new file mode 100644 index 0000000..5a6fdd0 Binary files /dev/null and b/public/fonts/eot/IRANSansWeb(FaNum).eot differ diff --git a/public/fonts/eot/IRANSansWeb(FaNum)_Black.eot b/public/fonts/eot/IRANSansWeb(FaNum)_Black.eot new file mode 100644 index 0000000..a012bc6 Binary files /dev/null and b/public/fonts/eot/IRANSansWeb(FaNum)_Black.eot differ diff --git a/public/fonts/eot/IRANSansWeb(FaNum)_Bold.eot b/public/fonts/eot/IRANSansWeb(FaNum)_Bold.eot new file mode 100644 index 0000000..82525e5 Binary files /dev/null and b/public/fonts/eot/IRANSansWeb(FaNum)_Bold.eot differ diff --git a/public/fonts/eot/IRANSansWeb(FaNum)_Light.eot b/public/fonts/eot/IRANSansWeb(FaNum)_Light.eot new file mode 100644 index 0000000..f899008 Binary files /dev/null and b/public/fonts/eot/IRANSansWeb(FaNum)_Light.eot differ diff --git a/public/fonts/eot/IRANSansWeb(FaNum)_Medium.eot b/public/fonts/eot/IRANSansWeb(FaNum)_Medium.eot new file mode 100644 index 0000000..117c2c8 Binary files /dev/null and b/public/fonts/eot/IRANSansWeb(FaNum)_Medium.eot differ diff --git a/public/fonts/eot/IRANSansWeb(FaNum)_UltraLight.eot b/public/fonts/eot/IRANSansWeb(FaNum)_UltraLight.eot new file mode 100644 index 0000000..9cd9b66 Binary files /dev/null and b/public/fonts/eot/IRANSansWeb(FaNum)_UltraLight.eot differ diff --git a/public/fonts/ttf/IRANSansWeb(FaNum).ttf b/public/fonts/ttf/IRANSansWeb(FaNum).ttf new file mode 100644 index 0000000..cd74265 Binary files /dev/null and b/public/fonts/ttf/IRANSansWeb(FaNum).ttf differ diff --git a/public/fonts/ttf/IRANSansWeb(FaNum)_Black.ttf b/public/fonts/ttf/IRANSansWeb(FaNum)_Black.ttf new file mode 100644 index 0000000..0f84dbf Binary files /dev/null and b/public/fonts/ttf/IRANSansWeb(FaNum)_Black.ttf differ diff --git a/public/fonts/ttf/IRANSansWeb(FaNum)_Bold.ttf b/public/fonts/ttf/IRANSansWeb(FaNum)_Bold.ttf new file mode 100644 index 0000000..6fa2412 Binary files /dev/null and b/public/fonts/ttf/IRANSansWeb(FaNum)_Bold.ttf differ diff --git a/public/fonts/ttf/IRANSansWeb(FaNum)_Light.ttf b/public/fonts/ttf/IRANSansWeb(FaNum)_Light.ttf new file mode 100644 index 0000000..d9000c9 Binary files /dev/null and b/public/fonts/ttf/IRANSansWeb(FaNum)_Light.ttf differ diff --git a/public/fonts/ttf/IRANSansWeb(FaNum)_Medium.ttf b/public/fonts/ttf/IRANSansWeb(FaNum)_Medium.ttf new file mode 100644 index 0000000..e20001c Binary files /dev/null and b/public/fonts/ttf/IRANSansWeb(FaNum)_Medium.ttf differ diff --git a/public/fonts/ttf/IRANSansWeb(FaNum)_UltraLight.ttf b/public/fonts/ttf/IRANSansWeb(FaNum)_UltraLight.ttf new file mode 100644 index 0000000..0072606 Binary files /dev/null and b/public/fonts/ttf/IRANSansWeb(FaNum)_UltraLight.ttf differ diff --git a/public/fonts/woff/IRANSansWeb(FaNum).woff b/public/fonts/woff/IRANSansWeb(FaNum).woff new file mode 100644 index 0000000..e34dfc4 Binary files /dev/null and b/public/fonts/woff/IRANSansWeb(FaNum).woff differ diff --git a/public/fonts/woff/IRANSansWeb(FaNum)_Black.woff b/public/fonts/woff/IRANSansWeb(FaNum)_Black.woff new file mode 100644 index 0000000..bbbca77 Binary files /dev/null and b/public/fonts/woff/IRANSansWeb(FaNum)_Black.woff differ diff --git a/public/fonts/woff/IRANSansWeb(FaNum)_Bold.woff b/public/fonts/woff/IRANSansWeb(FaNum)_Bold.woff new file mode 100644 index 0000000..05d933e Binary files /dev/null and b/public/fonts/woff/IRANSansWeb(FaNum)_Bold.woff differ diff --git a/public/fonts/woff/IRANSansWeb(FaNum)_Light.woff b/public/fonts/woff/IRANSansWeb(FaNum)_Light.woff new file mode 100644 index 0000000..fe80d47 Binary files /dev/null and b/public/fonts/woff/IRANSansWeb(FaNum)_Light.woff differ diff --git a/public/fonts/woff/IRANSansWeb(FaNum)_Medium.woff b/public/fonts/woff/IRANSansWeb(FaNum)_Medium.woff new file mode 100644 index 0000000..f13a870 Binary files /dev/null and b/public/fonts/woff/IRANSansWeb(FaNum)_Medium.woff differ diff --git a/public/fonts/woff/IRANSansWeb(FaNum)_UltraLight.woff b/public/fonts/woff/IRANSansWeb(FaNum)_UltraLight.woff new file mode 100644 index 0000000..9c653a4 Binary files /dev/null and b/public/fonts/woff/IRANSansWeb(FaNum)_UltraLight.woff differ diff --git a/public/fonts/woff2/IRANSansWeb(FaNum).woff2 b/public/fonts/woff2/IRANSansWeb(FaNum).woff2 new file mode 100644 index 0000000..30a377d Binary files /dev/null and b/public/fonts/woff2/IRANSansWeb(FaNum).woff2 differ diff --git a/public/fonts/woff2/IRANSansWeb(FaNum)_Black.woff2 b/public/fonts/woff2/IRANSansWeb(FaNum)_Black.woff2 new file mode 100644 index 0000000..0b15441 Binary files /dev/null and b/public/fonts/woff2/IRANSansWeb(FaNum)_Black.woff2 differ diff --git a/public/fonts/woff2/IRANSansWeb(FaNum)_Bold.woff2 b/public/fonts/woff2/IRANSansWeb(FaNum)_Bold.woff2 new file mode 100644 index 0000000..f2353b2 Binary files /dev/null and b/public/fonts/woff2/IRANSansWeb(FaNum)_Bold.woff2 differ diff --git a/public/fonts/woff2/IRANSansWeb(FaNum)_Light.woff2 b/public/fonts/woff2/IRANSansWeb(FaNum)_Light.woff2 new file mode 100644 index 0000000..562d663 Binary files /dev/null and b/public/fonts/woff2/IRANSansWeb(FaNum)_Light.woff2 differ diff --git a/public/fonts/woff2/IRANSansWeb(FaNum)_Medium.woff2 b/public/fonts/woff2/IRANSansWeb(FaNum)_Medium.woff2 new file mode 100644 index 0000000..a69f4d0 Binary files /dev/null and b/public/fonts/woff2/IRANSansWeb(FaNum)_Medium.woff2 differ diff --git a/public/fonts/woff2/IRANSansWeb(FaNum)_UltraLight.woff2 b/public/fonts/woff2/IRANSansWeb(FaNum)_UltraLight.woff2 new file mode 100644 index 0000000..1114f71 Binary files /dev/null and b/public/fonts/woff2/IRANSansWeb(FaNum)_UltraLight.woff2 differ diff --git a/public/images/change-password.svg b/public/images/change-password.svg deleted file mode 100644 index f3b65aa..0000000 --- a/public/images/change-password.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/images/dashboard.svg b/public/images/dashboard.svg deleted file mode 100644 index ea3f11b..0000000 --- a/public/images/dashboard.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/images/login.svg b/public/images/login.svg deleted file mode 100644 index e2854d2..0000000 --- a/public/images/login.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/images/logo.svg b/public/images/logo.svg deleted file mode 100644 index 5931dd4..0000000 --- a/public/images/logo.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - MARHABA - - diff --git a/public/images/upload-image.svg b/public/images/upload-image.svg new file mode 100644 index 0000000..c901145 --- /dev/null +++ b/public/images/upload-image.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json index 9eb981a..435a0c7 100644 --- a/public/locales/fa/app.json +++ b/public/locales/fa/app.json @@ -4,48 +4,158 @@ "dashboard": "داشبورد", "first_page": "خوش آمدید", "login": "ورود", - "login_navy": "ورود اعضای ناوگان", - "login_welfare_services": "ورود اعضای خدمات رفاهی", - "user_welfare_services": "خدمات رفاهی", + "pending": "درحال اجرا...", + "login_user_panel": "ورود به پنل کاربران", + "register_navy": "ثبت نام اعضای ناوگان", + "register_welfare_services": "ثبت نام اعضای خدمات رفاهی", "user_navy": "ناوگان", + "page_not_found": "صفحه مورد نظر یافت نشد", + "delete": "حذف", + "resend_code": "ارسال مجدد کد", + "Resend_code_in": "ارسال مجدد کد در", + "seconds_later": "ثانیه دیگر", + "upload_file_text": "بارگذاری فایل", "header": { "open_profile": "پروفایل", "edit_profile": "ویرایش پروفایل", "change_password": "تغییر رمز عبور", "logout": "خروج" }, + "notifications": { + "error_static_text": "عملیات با خطا مواجه شد", + "success_static_text": "عملیات با موفقیت انجام شد", + "code": "کد", + "success": "موفق", + "error": "خطا", + "pending": "درحال اجرا..." + }, + "Permission": { + "typography_you_dont_have_access": "شما دسترسی لازم برای مشاهده این صفحه را ندارید!", + "button_back_dashboard": "بازگشت به صفحه اصلی" + }, "Titles": { "title_login_page": "صفحه ورود", + "title_register_page": "صفحه ثبت نام", "title_login_navy_page": "ورود اعضای ناوگان", "title_login_welfare_services_page": "ورود اعضای خدمات رفاهی", "title_register_navy_page": "ثبت نام اعضای ناوگان", - "title_register_welfare_services_page": "ثبت نام اعضای خدمات رفاهی" + "title_register_welfare_services_page": "ثبت نام اعضای خدمات رفاهی", + "title_custom_404": "صفحه یافت نشد", + "title_custom_403": "عدم دسترسی", + "title_custom_500": "خطای سرور" + }, + "ErrorPage": { + "custom_404": "صفحه مورد نظر یافت نشد | 404", + "custom_500": "دسترسی به سامانه امکانپذیر نمی باشد دقایقی دیگر تلاش نمائید | 500", + "custom_403": "شما دسترسی به این بخش را ندارید | 403", + "link_routing_back_to": "بازگشت به", + "link_routing_previuos_page": "صفحه قبل", + "link_routing_main_page": "صفحه اصلی" }, "sidebar": { "dashboard": "داشبورد", - "loan-request": "درخواست وام", - "loan-follow-up": "پیگیری درخواست" + "add-request-loan": "درخواست وام", + "followUp-loan": "پیگیری درخواست", + "edit-request-loan": "ویرایش درخواست وام" }, "Authorization": { "typography_your_login_is_valid_and_you_do_not_need_to_login_again": "شما دسترسی لازم به این صفحه را دارید نیاز به ورود مجدد نیست.", "typography_your_access_to_this_page_has_expired_Please_login_again": "دسترسی شما منقضی شده است لطفا دوباره ورود نمایید.", - "typography_redirect_to": "رفتن به صفحه", + "typography_redirect_to": "درحال رفتن به صفحه", "typography_routing_previuos_page": "صفحه قبل...", "typography_routing_dashbaord_page": "داشبورد..." }, "LoginPage": { - "text_field_user_name": "نام کاربری", - "text_field_enter_your_username": "نام کاربری خود را وارد کنید", - "text_field_password": "رمز عبور", - "text_field_enter_your_password": "رمز عبور خود را وارد کنید", + "text_field_phone_number": "شماره تلفن", + "text_field_enter_your_phone_number": "شماره تلفن خود را وارد کنید", + "text_field_verification_code": "کد یکبار مصرف", + "text_field_enter_your_verification_code": "کد یکبار مصرف خود را وارد کنید", "button_submit": "ورود", "link_routing_back_to": "بازگشت به", "link_routing_previuos_page": "صفحه قبل", "link_routing_main_page": "صفحه اصلی", - "error_message_required": "اجباری!", - "button_make_account": "ایجاد حساب" + "error_message_phone_number": "شماره تلفن خود را وارد کنید!", + "error_message_verification_code": "کد یکبار مصرف خود را وارد کنید!", + "button_make_account": "ایجاد حساب", + "button_request_verification": "دریافت کد یکبارمصرف", + "sent_token_to": "ارسال کد یکبار مصرف به شماره", + "change_phone_number": "تغییر شماره" }, - "dashboard": { + "RegisterPage": { + "link_routing_back_to": "بازگشت به", + "link_routing_register": "صفحه انتخاب نوع ثبت نام", + "link_routing_login": "صفحه ورود", + "text_field_phone_number": "شماره تلفن", + "text_field_enter_your_phone_number": "شماره تلفن خود را وارد کنید", + "text_field_verification_code": "کد یکبار مصرف", + "text_field_enter_your_verification_code": "کد یکبار مصرف خود را وارد کنید", + "text_field_national_id": "کد ملی", + "text_field_enter_your_national_id": "کد ملی خود را وارد کنید", + "text_field_navgan_id": "شماره ناوگان", + "text_field_enter_your_navgan_id": "شماره ناوگان خود را وارد کنید", + "error_message_phone_number": "لطفا شماره تلفن خود را وارد کنید!", + "error_message_verification_code": "لطفا کد یکبار مصرف خود را وارد کنید!", + "error_message_national_id": "لطفا کد ملی خود را وارد کنید!", + "error_message_navgan_id": "لطفا کد ناوگان خود را وارد کنید!", + "button_request_verification": "دریافت کد یکبارمصرف", + "button_submit": "ثبت و ورود", + "button_back_to_send_data": "بازگشت", + "sent_token_to": "ارسال کد یکبار مصرف به شماره", + "change_phone_number": "تغییر شماره", + "complete_information": "مشخصات" + }, + "Dashboard": { "dashboard_page": "داشبورد" + }, + "LoanFollowUp": { + "loan_follow_up_page": "پیگیری درخواست", + "loan_request_correction": "اصلاح درخواست", + "loan_request_detail": "مشاهده جزئیات", + "request_number": "درخواست شماره" + }, + "LoanRequest": { + "loan_request_page": "ثبت درخواست وام", + "personal_info": "اطلاعات شخصی", + "uploading_documents": "اسناد", + "error_message_name": "لطفا نام خود را وارد کنید!", + "error_message_phone_number": "لطفا شماره تلفن خود را وارد کنید!", + "error_message_vehicle_type": "لطفا نوع وسیله نقلیه خود را وارد کنید!", + "error_message_plate_number": "لطفا شماره پلاک خود را وارد کنید!", + "error_message_navgan_id": "لطفا کد ناوگان خود را وارد کنید!", + "error_message_province": "لطفا استان خود را وارد کنید!", + "error_message_national_code": "لطفا کد ملی خود را وارد کنید!", + "error_message_shenasname_id": "لطفا شماره شناسنامه خود را وارد کنید!", + "text_field_phone_number": "شماره تلفن", + "text_field_enter_your_phone_number": "شماره تلفن خود را وارد کنید", + "text_field_name": "نام", + "text_field_enter_your_name": "نام خود را وارد کنید", + "text_field_vehicle_type": "نام وسیله نقلیه", + "text_field_enter_your_vehicle_type": "نام وسیله نقلیه خود را وارد کنید", + "text_field_province": "استان", + "text_field_enter_your_province": "استان خود را وارد کنید", + "text_field_navgan_id": "شماره ناوگان", + "text_field_enter_your_navgan_id": "شماره ناوگان خود را وارد کنید", + "text_field_national_code": "کد ملی", + "text_field_enter_your_national_code": "کد ملی خود را وارد کنید", + "text_field_shenasname_id": "شماره شناسنامه", + "text_field_enter_your_shenasname_id": "شماره شناسنامه خود را وارد کنید", + "text_field_plate_number": "شماره پلاک", + "text_field_enter_your_plate_number": "شماره پلاک خود را وارد کنید", + "button_submit": "ثبت درخواست", + "file_field_sherkat_naft_doc": "مجوز شرکت نفت", + "file_field_estate_doc": "سند مالکیت", + "file_field_agreement_doc": "موافقت نامه اصولی", + "error_message_sherkat_naft_doc": "مجوز شرکت نفت خود را وارد کنید", + "error_message_estate_doc": "سند مالکیت خود را وارد کنید", + "error_message_agreement_doc": "موافقت نامه اصولی خود را وارد کنید", + "file_field_shenasname_image": "تصویر شناسنامه", + "file_field_national_card_image": "تصویر کارت ملی", + "file_field_payan_khedmat_image": "تصویر کارت پایان خدمت", + "error_message_national_card_image": "تصویر کارت ملی خود را وارد کنید", + "error_message_shenasname_image": "تصویر شناسنامه خود را وارد کنید", + "error_message_payan_khedmat_image": "تصویر کارت پایان خدمت خود را وارد کنید" + }, + "EditLoanRequest": { + "edit_loan_request_page": "ویرایش درخواست وام" } } diff --git a/public/locales/fa/datatable.js b/public/locales/fa/datatable.js index e42208f..7713862 100644 --- a/public/locales/fa/datatable.js +++ b/public/locales/fa/datatable.js @@ -1,92 +1,92 @@ export const FA_DATATABLE_LOCALIZATION = { - actions: "Actions", - and: "and", - cancel: "Cancel", - changeFilterMode: "Change filter mode", - changeSearchMode: "Change search mode", - clearFilter: "Clear filter", - clearSearch: "Clear search", - clearSort: "Clear sort", - clickToCopy: "Click to copy", - collapse: "Collapse", - collapseAll: "Collapse all", - columnActions: "Column Actions", - copiedToClipboard: "Copied to clipboard", - dropToGroupBy: "Drop to group by {column}", - edit: "Edit", - expand: "Expand", - expandAll: "Expand all", - filterArrIncludes: "Includes", - filterArrIncludesAll: "Includes all", - filterArrIncludesSome: "Includes", - filterBetween: "Between", - filterBetweenInclusive: "Between Inclusive", - filterByColumn: "Filter by {column}", - filterContains: "Contains", - filterEmpty: "Empty", - filterEndsWith: "Ends With", - filterEquals: "Equals", - filterEqualsString: "Equals", - filterFuzzy: "Fuzzy", - filterGreaterThan: "Greater Than", - filterGreaterThanOrEqualTo: "Greater Than Or Equal To", - filterInNumberRange: "Between", - filterIncludesString: "Contains", - filterIncludesStringSensitive: "Contains", - filterLessThan: "Less Than", - filterLessThanOrEqualTo: "Less Than Or Equal To", - filterMode: "Filter Mode: {filterType}", - filterNotEmpty: "Not Empty", - filterNotEquals: "Not Equals", - filterStartsWith: "Starts With", - filterWeakEquals: "Equals", - filteringByColumn: "Filtering by {column} - {filterType} {filterValue}", - goToFirstPage: "Go to first page", - goToLastPage: "Go to last page", - goToNextPage: "Go to next page", - goToPreviousPage: "Go to previous page", - grab: "Grab", - groupByColumn: "Group by {column}", - groupedBy: "Grouped by ", - hideAll: "Hide all", - hideColumn: "Hide {column} column", - max: "Max", - min: "Min", - move: "Move", - noRecordsToDisplay: "No records to display", - noResultsFound: "No results found", - of: "of", - or: "or", - pinToLeft: "Pin to left", - pinToRight: "Pin to right", - resetColumnSize: "Reset column size", - resetOrder: "Reset order", - rowActions: "Row Actions", - rowNumber: "#", - rowNumbers: "Row Numbers", - rowsPerPage: "Rows per page", - save: "Save", - search: "Search", - selectedCountOfRowCountRowsSelected: - "{selectedCount} of {rowCount} row(s) selected", - select: "Select", - showAll: "Show all", - showAllColumns: "Show all columns", - showHideColumns: "Show/Hide columns", - showHideFilters: "Show/Hide filters", - showHideSearch: "Show/Hide search", - sortByColumnAsc: "Sort by {column} ascending", - sortByColumnDesc: "Sort by {column} descending", - sortedByColumnAsc: "Sorted by {column} ascending", - sortedByColumnDesc: "Sorted by {column} descending", - thenBy: ", then by ", - toggleDensity: "Toggle density", - toggleFullScreen: "Toggle full screen", - toggleSelectAll: "Toggle select all", - toggleSelectRow: "Toggle select row", - toggleVisibility: "Toggle visibility", - ungroupByColumn: "Ungroup by {column}", - unpin: "Unpin", - unpinAll: "Unpin all", - unsorted: "Unsorted", + actions: "Actions", + and: "and", + cancel: "Cancel", + changeFilterMode: "Change filter mode", + changeSearchMode: "Change search mode", + clearFilter: "Clear filter", + clearSearch: "Clear search", + clearSort: "Clear sort", + clickToCopy: "Click to copy", + collapse: "Collapse", + collapseAll: "Collapse all", + columnActions: "Column Actions", + copiedToClipboard: "Copied to clipboard", + dropToGroupBy: "Drop to group by {column}", + edit: "Edit", + expand: "Expand", + expandAll: "Expand all", + filterArrIncludes: "Includes", + filterArrIncludesAll: "Includes all", + filterArrIncludesSome: "Includes", + filterBetween: "Between", + filterBetweenInclusive: "Between Inclusive", + filterByColumn: "Filter by {column}", + filterContains: "Contains", + filterEmpty: "Empty", + filterEndsWith: "Ends With", + filterEquals: "Equals", + filterEqualsString: "Equals", + filterFuzzy: "Fuzzy", + filterGreaterThan: "Greater Than", + filterGreaterThanOrEqualTo: "Greater Than Or Equal To", + filterInNumberRange: "Between", + filterIncludesString: "Contains", + filterIncludesStringSensitive: "Contains", + filterLessThan: "Less Than", + filterLessThanOrEqualTo: "Less Than Or Equal To", + filterMode: "Filter Mode: {filterType}", + filterNotEmpty: "Not Empty", + filterNotEquals: "Not Equals", + filterStartsWith: "Starts With", + filterWeakEquals: "Equals", + filteringByColumn: "Filtering by {column} - {filterType} {filterValue}", + goToFirstPage: "Go to first page", + goToLastPage: "Go to last page", + goToNextPage: "Go to next page", + goToPreviousPage: "Go to previous page", + grab: "Grab", + groupByColumn: "Group by {column}", + groupedBy: "Grouped by ", + hideAll: "Hide all", + hideColumn: "Hide {column} column", + max: "Max", + min: "Min", + move: "Move", + noRecordsToDisplay: "No records to display", + noResultsFound: "No results found", + of: "of", + or: "or", + pinToLeft: "Pin to left", + pinToRight: "Pin to right", + resetColumnSize: "Reset column size", + resetOrder: "Reset order", + rowActions: "Row Actions", + rowNumber: "#", + rowNumbers: "Row Numbers", + rowsPerPage: "Rows per page", + save: "Save", + search: "Search", + selectedCountOfRowCountRowsSelected: + "{selectedCount} of {rowCount} row(s) selected", + select: "Select", + showAll: "Show all", + showAllColumns: "Show all columns", + showHideColumns: "Show/Hide columns", + showHideFilters: "Show/Hide filters", + showHideSearch: "Show/Hide search", + sortByColumnAsc: "Sort by {column} ascending", + sortByColumnDesc: "Sort by {column} descending", + sortedByColumnAsc: "Sorted by {column} ascending", + sortedByColumnDesc: "Sorted by {column} descending", + thenBy: ", then by ", + toggleDensity: "Toggle density", + toggleFullScreen: "Toggle full screen", + toggleSelectAll: "Toggle select all", + toggleSelectRow: "Toggle select row", + toggleVisibility: "Toggle visibility", + ungroupByColumn: "Ungroup by {column}", + unpin: "Unpin", + unpinAll: "Unpin all", + unsorted: "Unsorted", }; diff --git a/src/components/dashboard/first/index.jsx b/src/components/dashboard/first/index.jsx index c693380..3d1c29e 100644 --- a/src/components/dashboard/first/index.jsx +++ b/src/components/dashboard/first/index.jsx @@ -1,7 +1,7 @@ import DashboardLayouts from "@/layouts/dashboardLayouts"; -const DashboardFirstComponent = () => { - return ; +const FirstComponent = () => { + return ; }; -export default DashboardFirstComponent; +export default FirstComponent; diff --git a/src/components/dashboard/loan-follow-up/index.jsx b/src/components/dashboard/loan-follow-up/index.jsx deleted file mode 100644 index e69147e..0000000 --- a/src/components/dashboard/loan-follow-up/index.jsx +++ /dev/null @@ -1,19 +0,0 @@ -import CenterLayout from "@/layouts/CenterLayout"; -import DashboardLayouts from "@/layouts/dashboardLayouts"; -import useUser from "@/lib/app/hooks/useUser"; -import { useTranslations } from "next-intl"; -import React from "react"; - -const DashboardLoanFollowUpComponent = () => { - const t = useTranslations(); - const { token } = useUser(); - return ( - - -

چه کشکی چه پشمی

-
-
- ); -}; - -export default DashboardLoanFollowUpComponent; diff --git a/src/components/dashboard/loan-request/index.jsx b/src/components/dashboard/loan-request/index.jsx deleted file mode 100644 index b13cf78..0000000 --- a/src/components/dashboard/loan-request/index.jsx +++ /dev/null @@ -1,19 +0,0 @@ -import CenterLayout from "@/layouts/CenterLayout"; -import DashboardLayouts from "@/layouts/dashboardLayouts"; -import useUser from "@/lib/app/hooks/useUser"; -import { useTranslations } from "next-intl"; -import React from "react"; - -const DashboardLoanRequestComponent = () => { - const t = useTranslations(); - const { token } = useUser(); - return ( - - -

نکنه وامم میخوای؟؟؟

-
-
- ); -}; - -export default DashboardLoanRequestComponent; diff --git a/src/components/dashboard/navgan/add-request-loan/forms/AddForm.jsx b/src/components/dashboard/navgan/add-request-loan/forms/AddForm.jsx new file mode 100644 index 0000000..760fed1 --- /dev/null +++ b/src/components/dashboard/navgan/add-request-loan/forms/AddForm.jsx @@ -0,0 +1,489 @@ +import Notifications from "@/core/components/notifications"; +import SelectBox from "@/core/components/SelectBox"; +import StyledForm from "@/core/components/StyledForm"; +import UploadSystem from "@/core/components/UploadSystem"; +import {GET_PROVINCE_LIST, SEND_LOAN_REQUEST_NAVGAN,} from "@/core/data/apiRoutes"; +import useDirection from "@/lib/app/hooks/useDirection"; +import useUser from "@/lib/app/hooks/useUser"; +import DataSaverOnIcon from "@mui/icons-material/DataSaverOn"; +import {Box, Button, Stack, TextField} from "@mui/material"; +import axios from "axios"; +import {Field, Formik} from "formik"; +import {useTranslations} from "next-intl"; +import {useEffect, useState} from "react"; +import * as Yup from "yup"; + +const AddFormComponent = () => { + const t = useTranslations(); + const {directionApp} = useDirection(); + const {token} = useUser(); + + // get province list + const [provinceList, setProvinceList] = useState([]); + useEffect(() => { + axios + .get(GET_PROVINCE_LIST, { + headers: {Authorization: `Bearer ${token}`}, + }) + .then(({data}) => { + const formattedData = data.map((province, index) => ({ + id: index, + name: province.name, + value: province.id, + })); + setProvinceList(formattedData); + }) + .catch((error) => { + Notifications(t, error.response); + }); + }, []); + // end get province list + + // upload files + const [selectedImageShenasname, setSelectedImageShenasname] = useState( + "/images/upload-image.svg" + ); + const [fileTypeShenasname, setFileTypeShenasname] = useState(null); + const [fileNameShenasname, setFileNameShenasname] = useState(null); + const [selectedImageNationalCard, setSelectedImageNationalCard] = useState( + "/images/upload-image.svg" + ); + const [fileTypeNationalCard, setFileTypeNationalCard] = useState(null); + const [fileNameNationalCard, setFileNameNationalCard] = useState(null); + + const handleUploadChangeShenasname = (event, setFieldValue) => { + const uploadedFile = event.target?.files?.[0]; + if (uploadedFile) { + const fileType = event.target?.files?.[0].type; + const fileName = event.target?.files?.[0].name; + setSelectedImageShenasname(URL.createObjectURL(uploadedFile)); + setFileTypeShenasname(fileType); + setFileNameShenasname(fileName); + setFieldValue("shenasname_img", uploadedFile); + } + }; + const handleUploadChangeNationalCard = (event, setFieldValue) => { + const uploadedFile = event.target?.files?.[0]; + const fileType = event.target.files[0].type; + const fileName = event.target.files[0].name; + if (uploadedFile) { + setSelectedImageNationalCard(URL.createObjectURL(uploadedFile)); + setFileTypeNationalCard(fileType); + setFileNameNationalCard(fileName); + setFieldValue("national_card_img", uploadedFile); + } + }; + // end upload files + + // initial values + const initialValues = { + name: "", + phone_number: "", + vehicle_type: "", + plate_number: "", + province: "", + navgan_id: "", + national_code: "", + shenasname_id: "", + national_card_img: null, + shenasname_img: null, + }; + // end initial values + + // validation + const validationSchema = Yup.object().shape({ + name: Yup.string().required(t("LoanRequest.error_message_name")), + phone_number: Yup.string().required( + t("LoanRequest.error_message_phone_number") + ), + vehicle_type: Yup.string().required( + t("LoanRequest.error_message_vehicle_type") + ), + plate_number: Yup.string().required( + t("LoanRequest.error_message_plate_number") + ), + navgan_id: Yup.string().required(t("LoanRequest.error_message_navgan_id")), + province: Yup.string().required(t("LoanRequest.error_message_province")), + national_code: Yup.string().required( + t("LoanRequest.error_message_national_code") + ), + shenasname_id: Yup.string().required( + t("LoanRequest.error_message_shenasname_id") + ), + }); + // end validation + + // submit + const handleSubmit = async (values, props) => { + Notifications(t, undefined); + const formData = new FormData(); + formData.append("name", values.name); + formData.append("phone_number", values.phone_number); + formData.append("vehicle_type", values.vehicle_type); + formData.append("plate_number", values.plate_number); + formData.append("province_id", values.province); + formData.append("navgan_id", values.navgan_id); + formData.append("national_code", values.national_code); + formData.append("shenasname_id", values.shenasname_id); + if (values.shenasname_img != null) + formData.append("shenasname_image", values.shenasname_img); + if (values.national_card_img != null) + formData.append("national_card_image", values.national_card_img); + + await axios + .post(SEND_LOAN_REQUEST_NAVGAN, formData, { + headers: { + Authorization: `Bearer ${token}`, + "Content-Type": "multipart/form-data", + }, + }) + .then(function (response) { + Notifications(t, response); + }) + .catch(function (error) { + Notifications(t, error.response); + props.setSubmitting(false); + }); + }; + // end submit + + return ( + + {(props) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + handleUploadChangeShenasname(e, props.setFieldValue) + } + setselectedImage={setSelectedImageShenasname} + setFieldValue={props.setFieldValue} + fieldname="shenasname_img" + fileType={fileTypeShenasname} + fileName={fileNameShenasname} + imageAlt={t("app_name")} + imageSize={[300 /*width*/, 150 /*height*/]} + label={t("LoanRequest.file_field_shenasname_image")} + /> + + handleUploadChangeNationalCard(e, props.setFieldValue) + } + setselectedImage={setSelectedImageNationalCard} + setFieldValue={props.setFieldValue} + fieldname="national_card_img" + fileType={fileTypeNationalCard} + fileName={fileNameNationalCard} + imageAlt={t("app_name")} + imageSize={[300 /*width*/, 150 /*height*/]} + label={t("LoanRequest.file_field_national_card_image")} + /> + + + + + + + )} + + ); +}; + +export default AddFormComponent; diff --git a/src/components/dashboard/navgan/add-request-loan/index.jsx b/src/components/dashboard/navgan/add-request-loan/index.jsx new file mode 100644 index 0000000..cd9d359 --- /dev/null +++ b/src/components/dashboard/navgan/add-request-loan/index.jsx @@ -0,0 +1,30 @@ +import CenterLayout from "@/layouts/CenterLayout"; +import DashboardLayouts from "@/layouts/dashboardLayouts"; +import useUser from "@/lib/app/hooks/useUser"; +import {Box, Chip, Divider} from "@mui/material"; +import {useTranslations} from "next-intl"; +import AddFormComponent from "@/components/dashboard/navgan/add-request-loan/forms/AddForm"; + +const LoanRequestComponent = () => { + const t = useTranslations(); + const {user} = useUser(); + + return ( + + + + + + + + + + + ); +}; + +export default LoanRequestComponent; diff --git a/src/components/dashboard/navgan/followUp-loan/RequestCard.jsx b/src/components/dashboard/navgan/followUp-loan/RequestCard.jsx new file mode 100644 index 0000000..6e5dfd3 --- /dev/null +++ b/src/components/dashboard/navgan/followUp-loan/RequestCard.jsx @@ -0,0 +1,29 @@ +import {Card, CardContent, CardHeader, Grid, Typography} from "@mui/material"; +import SellIcon from '@mui/icons-material/Sell'; +import {useTranslations} from "next-intl"; + + +const RequestCard = ({item}) => { + const t = useTranslations(); + return ( + + + } + title={`${t("LoanFollowUp.request_number")}: (${item.id})`} + subheader={item.latest_history_created_at} + /> + + + {item.loan_state} + + + + + ); +}; + +export default RequestCard; \ No newline at end of file diff --git a/src/components/dashboard/navgan/followUp-loan/index.jsx b/src/components/dashboard/navgan/followUp-loan/index.jsx new file mode 100644 index 0000000..de3176c --- /dev/null +++ b/src/components/dashboard/navgan/followUp-loan/index.jsx @@ -0,0 +1,60 @@ +import DashboardLayouts from "@/layouts/dashboardLayouts"; +import { + Grid, + Stack, +} from "@mui/material"; +import {useEffect, useState} from "react"; +import {SHOW_LOAN_REQUEST_NAVGAN} from "@/core/data/apiRoutes"; +import useLoading from "@/lib/app/hooks/useLoading"; +import useRequest from "@/lib/app/hooks/useRequest"; +import moment from "jalali-moment"; +import RequestCard from "@/components/dashboard/navgan/followUp-loan/RequestCard"; + +const LoanFollowUpComponent = () => { + const requestServer = useRequest(); + const {setLoadingPage} = useLoading(); + const [requestsList, setRequestsList] = useState([]); + // get form data + useEffect(() => { + setLoadingPage(true) + requestServer(SHOW_LOAN_REQUEST_NAVGAN, "get", {auth: true, notification: false}) + .then(function ({data}) { + const items = data.data; + const formattedData = items.map((item, index) => ({ + id: item.id, + latest_history_created_at: moment(item.latest_history_created_at).locale("fa").format("HH:mm | YYYY/MM/DD"), + state_id: item.state_id, + loan_state: item.loan_state, + })); + setRequestsList(formattedData); + setLoadingPage(false) + }) + .catch(function (error) { + }) + }, []); + + return ( + + + + {requestsList.map((item, index) => ( + + ))} + + + + ); +}; + +export default LoanFollowUpComponent; diff --git a/src/components/dashboard/refahi/add-request-loan/forms/AddForm.jsx b/src/components/dashboard/refahi/add-request-loan/forms/AddForm.jsx new file mode 100644 index 0000000..06a40fc --- /dev/null +++ b/src/components/dashboard/refahi/add-request-loan/forms/AddForm.jsx @@ -0,0 +1,424 @@ +import StyledForm from "@/core/components/StyledForm"; +import UploadSystem from "@/core/components/UploadSystem"; +import {GET_PROVINCE_LIST, SEND_LOAN_REQUEST_WELFARE} from "@/core/data/apiRoutes"; +import useDirection from "@/lib/app/hooks/useDirection"; +import useUser from "@/lib/app/hooks/useUser"; +import DataSaverOnIcon from "@mui/icons-material/DataSaverOn"; +import {Box, Button, Chip, Divider, Stack, TextField} from "@mui/material"; +import {Field, Formik} from "formik"; +import {useTranslations} from "next-intl"; +import {useEffect, useState} from "react"; +import * as Yup from "yup"; +import SelectBox from "@/core/components/SelectBox"; +import useRequest from "@/lib/app/hooks/useRequest"; + +const AddFormComponent = () => { + const t = useTranslations(); + const {directionApp} = useDirection(); + const {token} = useUser(); + const requestServer = useRequest() + + const [provinceList, setProvinceList] = useState([]); + + // get province list + useEffect(() => { + requestServer(GET_PROVINCE_LIST, "get", {auth: true, notification: false}) + .then(function ({data}) { + const formattedData = data.map((province, index) => ({ + id: index, + name: province.name, + value: province.id, + })); + setProvinceList(formattedData); + }).catch(() => { + }) + }, []); + // end get province list + + // initial values, validation and request action of form + const initialValues = { + name: "", + phone_number: "", + province: "", + national_code: "", + shenasname_id: "", + sherkat_naft_doc: null, + estate_doc: null, + agreement_doc: null, + national_card_image: null, + shenasname_image: null, + payan_khedmat_image: null, + }; + + const validationSchema = Yup.object().shape({ + name: Yup.string().required(t("LoanRequest.error_message_name")), + phone_number: Yup.string().required( + t("LoanRequest.error_message_phone_number") + ), + province: Yup.string().required(t("LoanRequest.error_message_province")), + national_code: Yup.string().required( + t("LoanRequest.error_message_national_code") + ), + shenasname_id: Yup.string().required( + t("LoanRequest.error_message_shenasname_id") + ), + sherkat_naft_doc: Yup.mixed().required(t("LoanRequest.error_message_sherkat_naft_doc")), + estate_doc: Yup.mixed().required(t("LoanRequest.error_message_estate_doc")), + agreement_doc: Yup.mixed().required(t("LoanRequest.error_message_agreement_doc")), + national_card_image: Yup.mixed().required(t("LoanRequest.error_message_national_card_image")), + shenasname_image: Yup.mixed().required(t("LoanRequest.error_message_shenasname_image")), + payan_khedmat_image: Yup.mixed().required(t("LoanRequest.error_message_payan_khedmat_image")), + }); + const handleSubmit = (values, props) => { + const formData = new FormData(); + formData.append("name", values.name); + formData.append("phone_number", values.phone_number); + formData.append("province_id", values.province); + formData.append("national_id", values.national_code); + formData.append("shenasname_id", values.shenasname_id); + if (values.sherkat_naft_doc != null) + formData.append("sherkat_naft_doc", values.sherkat_naft_doc); + if (values.estate_doc != null) + formData.append("estate_doc", values.estate_doc); + if (values.agreement_doc != null) + formData.append("agreement_doc", values.agreement_doc); + if (values.shenasname_image != null) + formData.append("shenasname_image", values.shenasname_image); + if (values.national_card_image != null) + formData.append("national_card_image", values.national_card_image); + if (values.payan_khedmat_image != null) + formData.append("payan_khedmat_image", values.payan_khedmat_image); + requestServer(SEND_LOAN_REQUEST_WELFARE, "post", {auth: true, data: formData}) + .then(function (response) { + }) + .catch(function (error) { + }) + .finally(function () { + props.setSubmitting(false); + }); + }; + // end initial values, validation and request action of form + + return ( + + {(props) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + )} + + ); +}; + +export default AddFormComponent; \ No newline at end of file diff --git a/src/components/dashboard/refahi/add-request-loan/index.jsx b/src/components/dashboard/refahi/add-request-loan/index.jsx new file mode 100644 index 0000000..feb8df0 --- /dev/null +++ b/src/components/dashboard/refahi/add-request-loan/index.jsx @@ -0,0 +1,18 @@ +import DashboardLayouts from "@/layouts/dashboardLayouts"; +import useUser from "@/lib/app/hooks/useUser"; +import {Box, Chip, Divider} from "@mui/material"; +import {useTranslations} from "next-intl"; +import AddFormComponent from "@/components/dashboard/refahi/add-request-loan/forms/AddForm"; + +const LoanRequestComponent = () => { + const t = useTranslations(); + const {user} = useUser(); + + return ( + + + + ); +}; + +export default LoanRequestComponent; diff --git a/src/components/dashboard/refahi/edit-request-loan/forms/EditForm.jsx b/src/components/dashboard/refahi/edit-request-loan/forms/EditForm.jsx new file mode 100644 index 0000000..9ea22c2 --- /dev/null +++ b/src/components/dashboard/refahi/edit-request-loan/forms/EditForm.jsx @@ -0,0 +1,446 @@ +import StyledForm from "@/core/components/StyledForm"; +import UploadSystem from "@/core/components/UploadSystem"; +import {GET_PROVINCE_LIST, UPDATE_LOAN_REQUEST_WELFARE, DETAILS_LOAN_REQUEST_WELFARE} from "@/core/data/apiRoutes"; +import useDirection from "@/lib/app/hooks/useDirection"; +import useUser from "@/lib/app/hooks/useUser"; +import DataSaverOnIcon from "@mui/icons-material/DataSaverOn"; +import {Box, Button, Chip, Divider, Stack, TextField} from "@mui/material"; +import axios from "axios"; +import {Field, Formik} from "formik"; +import {useTranslations} from "next-intl"; +import {useEffect, useMemo, useState} from "react"; +import * as Yup from "yup"; +import SelectBox from "@/core/components/SelectBox"; +import useRequest from "@/lib/app/hooks/useRequest"; +import {useRouter} from "next/router"; +import useLoading from "@/lib/app/hooks/useLoading"; + +const EditFormComponent = () => { + const t = useTranslations(); + const {directionApp} = useDirection(); + const {token} = useUser(); + const requestServer = useRequest(); + const router = useRouter(); + const {setLoadingPage} = useLoading(); + + const [provinceList, setProvinceList] = useState(null); + const [initialValues, setInitialValues] = useState(null); + + // get province list + useEffect(() => { + setLoadingPage(true) + requestServer(GET_PROVINCE_LIST, "get", {auth: true, notification: false}) + .then(function ({data}) { + const formattedData = data.map((province, index) => ({ + id: index, + name: province.name, + value: province.id, + })); + setProvinceList(formattedData); + }).catch(() => { + }); + }, []); + + + // get form data + useEffect(() => { + if (!provinceList) return; + requestServer(DETAILS_LOAN_REQUEST_WELFARE + router.query.id, "get", {auth: true, notification: false}) + .then(function ({data}) { + const item = data.data; + const formattedData = { + name: item.name, + phone_number: item.phone_number, + province_id: item.province_id, + national_id: item.national_id, + shenasname_id: item.shenasname_id, + sherkat_naft_doc: item.sherkat_naft_doc, + estate_doc: item.estate_doc, + agreement_doc: item.agreement_doc, + national_card_image: item.national_card_image, + shenasname_image: item.shenasname_image, + payan_khedmat_image: item.payan_khedmat_image, + } + setInitialValues(formattedData); + setLoadingPage(false) + }) + .catch(() => { + }) + }, [provinceList]); + + // validation and request action of form + const validationSchema = Yup.object().shape({ + name: Yup.string().required(t("LoanRequest.error_message_name")), + phone_number: Yup.string().required( + t("LoanRequest.error_message_phone_number") + ), + province_id: Yup.string().required(t("LoanRequest.error_message_province")), + national_id: Yup.string().required(t("LoanRequest.error_message_national_code")), + shenasname_id: Yup.string().required(t("LoanRequest.error_message_shenasname_id")), + sherkat_naft_doc: Yup.mixed().required(t("LoanRequest.error_message_sherkat_naft_doc")), + estate_doc: Yup.mixed().required(t("LoanRequest.error_message_estate_doc")), + agreement_doc: Yup.mixed().required(t("LoanRequest.error_message_agreement_doc")), + national_card_image: Yup.mixed().required(t("LoanRequest.error_message_national_card_image")), + shenasname_image: Yup.mixed().required(t("LoanRequest.error_message_shenasname_image")), + payan_khedmat_image: Yup.mixed().required(t("LoanRequest.error_message_payan_khedmat_image")), + }); + + const handleSubmit = (values, props) => { + const formData = new FormData(); + formData.append("name", values.name); + formData.append("phone_number", values.phone_number); + formData.append("province_id", values.province_id); + formData.append("national_id", values.national_id); + formData.append("shenasname_id", values.shenasname_id); + if (values.sherkat_naft_doc != initialValues.sherkat_naft_doc) + formData.append("sherkat_naft_doc", values.sherkat_naft_doc); + if (values.estate_doc != initialValues.estate_doc) + formData.append("estate_doc", values.estate_doc); + if (values.agreement_doc != initialValues.agreement_doc) + formData.append("agreement_doc", values.agreement_doc); + if (values.shenasname_image != initialValues.shenasname_image) + formData.append("shenasname_image", values.shenasname_image); + if (values.national_card_image != initialValues.national_card_image) + formData.append("national_card_image", values.national_card_image); + if (values.payan_khedmat_image != initialValues.payan_khedmat_image) + formData.append("payan_khedmat_image", values.payan_khedmat_image); + + requestServer(UPDATE_LOAN_REQUEST_WELFARE + router.query.id, "post", {auth: true, data: formData}) + .then(function (response) { + }) + .catch(function (error) { + }) + .finally(function () { + props.setSubmitting(false); + }); + }; + if (!initialValues) return ""; + return ( + + {(props) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + )} + + ); +}; + +export default EditFormComponent; \ No newline at end of file diff --git a/src/components/dashboard/refahi/edit-request-loan/index.jsx b/src/components/dashboard/refahi/edit-request-loan/index.jsx new file mode 100644 index 0000000..4be62ff --- /dev/null +++ b/src/components/dashboard/refahi/edit-request-loan/index.jsx @@ -0,0 +1,17 @@ +import DashboardLayouts from "@/layouts/dashboardLayouts"; +import useUser from "@/lib/app/hooks/useUser"; +import {useTranslations} from "next-intl"; +import EditFormComponent from "@/components/dashboard/refahi/edit-request-loan/forms/EditForm"; + +const LoanRequestComponent = () => { + const t = useTranslations(); + const {user} = useUser(); + + return ( + + + + ); +}; + +export default LoanRequestComponent; \ No newline at end of file diff --git a/src/components/dashboard/refahi/followUp-loan/RequestCard.jsx b/src/components/dashboard/refahi/followUp-loan/RequestCard.jsx new file mode 100644 index 0000000..799d296 --- /dev/null +++ b/src/components/dashboard/refahi/followUp-loan/RequestCard.jsx @@ -0,0 +1,52 @@ +import { + Card, + CardContent, + CardHeader, + Grid, IconButton, Tooltip, + Typography, +} from "@mui/material"; +import SellIcon from '@mui/icons-material/Sell'; +import EditIcon from '@mui/icons-material/Edit'; +import {useTranslations} from "next-intl"; +import {NextLinkComposed} from "@/core/components/LinkRouting"; + + +const RequestCard = ({item}) => { + const t = useTranslations(); + return ( + + + } + title={`${t("LoanFollowUp.request_number")}: (${item.id})`} + subheader={item.latest_history_created_at} + action={ + item.state_id === 7 ? ( // Use the ternary operator or if/else inside curly braces + + + + + + ) : null + } + /> + + + {item.loan_state} + + + + + ); +}; + +export default RequestCard; \ No newline at end of file diff --git a/src/components/dashboard/refahi/followUp-loan/index.jsx b/src/components/dashboard/refahi/followUp-loan/index.jsx new file mode 100644 index 0000000..331bab0 --- /dev/null +++ b/src/components/dashboard/refahi/followUp-loan/index.jsx @@ -0,0 +1,60 @@ +import DashboardLayouts from "@/layouts/dashboardLayouts"; +import { + Grid, + Stack, +} from "@mui/material"; +import {useEffect, useState} from "react"; +import {SHOW_LOAN_REQUEST_WELFARE} from "@/core/data/apiRoutes"; +import useLoading from "@/lib/app/hooks/useLoading"; +import useRequest from "@/lib/app/hooks/useRequest"; +import moment from "jalali-moment"; +import RequestCard from "@/components/dashboard/refahi/followUp-loan/RequestCard"; + +const LoanFollowUpComponent = () => { + const requestServer = useRequest(); + const {setLoadingPage} = useLoading(); + const [requestsList, setRequestsList] = useState([]); + // get form data + useEffect(() => { + setLoadingPage(true) + requestServer(SHOW_LOAN_REQUEST_WELFARE, "get", {auth: true, notification: false}) + .then(function ({data}) { + const items = data.data; + const formattedData = items.map((item, index) => ({ + id: item.id, + latest_history_created_at: moment(item.latest_history_created_at).locale("fa").format("HH:mm | YYYY/MM/DD"), + state_id: item.state_id, + loan_state: item.loan_state, + })); + setRequestsList(formattedData); + setLoadingPage(false) + }) + .catch(function (error) { + }) + }, []); + + return ( + + + + {requestsList.map((item, index) => ( + + ))} + + + + ); +}; + +export default LoanFollowUpComponent; diff --git a/src/components/errors/403.jsx b/src/components/errors/403.jsx new file mode 100644 index 0000000..ce91443 --- /dev/null +++ b/src/components/errors/403.jsx @@ -0,0 +1,37 @@ +import CenterLayout from "@/layouts/CenterLayout"; +import FullPageLayout from "@/layouts/FullPageLayout"; +import {Button, Typography} from "@mui/material"; +import {NextLinkComposed} from "@/core/components/LinkRouting"; +import {useTranslations} from "next-intl"; +import TitlePage from "@/core/components/TitlePage"; +import Svg403 from "@/core/components/svgs/Svg403"; + +const UnAuthorizedComponent = () => { + const t = useTranslations(); + + return ( + <> + + + + + + {t("ErrorPage.custom_403")} + + + + + + ); +}; + +export default UnAuthorizedComponent; diff --git a/src/components/errors/404.jsx b/src/components/errors/404.jsx new file mode 100644 index 0000000..acfd418 --- /dev/null +++ b/src/components/errors/404.jsx @@ -0,0 +1,37 @@ +import CenterLayout from "@/layouts/CenterLayout"; +import FullPageLayout from "@/layouts/FullPageLayout"; +import {Button, Typography} from "@mui/material"; +import {NextLinkComposed} from "@/core/components/LinkRouting"; +import {useTranslations} from "next-intl"; +import TitlePage from "@/core/components/TitlePage"; +import Svg404 from "@/core/components/svgs/Svg404"; + +const NotFoundComponent = () => { + const t = useTranslations(); + + return ( + <> + + + + + + {t("ErrorPage.custom_404")} + + + + + + ); +}; + +export default NotFoundComponent; diff --git a/src/components/errors/500.jsx b/src/components/errors/500.jsx new file mode 100644 index 0000000..5a19eda --- /dev/null +++ b/src/components/errors/500.jsx @@ -0,0 +1,37 @@ +import CenterLayout from "@/layouts/CenterLayout"; +import FullPageLayout from "@/layouts/FullPageLayout"; +import {Button, Typography} from "@mui/material"; +import {NextLinkComposed} from "@/core/components/LinkRouting"; +import {useTranslations} from "next-intl"; +import TitlePage from "@/core/components/TitlePage"; +import Svg500 from "@/core/components/svgs/Svg500"; + +const ServerErrorComponent = () => { + const t = useTranslations(); + + return ( + <> + + + + + + {t("ErrorPage.custom_500")} + + + + + + ); +}; + +export default ServerErrorComponent; diff --git a/src/components/first/index.jsx b/src/components/first/index.jsx index 9a1be52..c949fac 100644 --- a/src/components/first/index.jsx +++ b/src/components/first/index.jsx @@ -1,66 +1,56 @@ -import dahsboardImage from "&/images/dashboard.svg"; -import { NextLinkComposed } from "@/core/components/LinkRouting"; -import StyledImage from "@/core/components/StyledImage"; +import {NextLinkComposed} from "@/core/components/LinkRouting"; import CenterLayout from "@/layouts/CenterLayout"; import FullPageLayout from "@/layouts/FullPageLayout"; import useUser from "@/lib/app/hooks/useUser"; -import { Box, Button, Divider, Typography } from "@mui/material"; -import { useTranslations } from "next-intl"; +import {Button, Stack, Typography} from "@mui/material"; +import {useTranslations} from "next-intl"; +import SvgDashboard from "@/core/components/svgs/SvgDashboard"; const FirstComponent = () => { - const t = useTranslations(); - const { isAuth } = useUser(); + const t = useTranslations(); + const {isAuth} = useUser(); - return ( - - - - - {t("app_name")} - - {isAuth ? ( - - ) : ( - - - - - - )} - - - ); + return ( + + + + + {t("app_name")} + + {isAuth ? ( + + ) : ( + + )} + + + v{process.env.NEXT_PUBLIC_API_VERSION} + + + ); }; export default FirstComponent; diff --git a/src/components/login-navy/index.jsx b/src/components/login-navy/index.jsx deleted file mode 100644 index 70abf0e..0000000 --- a/src/components/login-navy/index.jsx +++ /dev/null @@ -1,170 +0,0 @@ -import LinkRouting from "@/core/components/LinkRouting"; -// import Notifications from "@/core/components/notifications"; -import PasswordField from "@/core/components/PasswordField"; -import StyledForm from "@/core/components/StyledForm"; -// import { GET_USER_TOKEN } from "@/core/data/apiRoutes"; -import CenterLayout from "@/layouts/CenterLayout"; -import FullPageLayout from "@/layouts/FullPageLayout"; -import useDirection from "@/lib/app/hooks/useDirection"; -import useUser from "@/lib/app/hooks/useUser"; -import LoginIcon from "@mui/icons-material/Login"; -import PersonAddIcon from "@mui/icons-material/PersonAdd"; -import { - Box, - Button, - Container, - Paper, - Stack, - TextField, - Typography, -} from "@mui/material"; -// import axios from "axios"; -import { Field, Formik } from "formik"; -import { useTranslations } from "next-intl"; -import Image from "next/image"; -import { useSearchParams } from "next/navigation"; -import * as Yup from "yup"; - -const LoginComponent = () => { - const t = useTranslations(); - const { directionApp } = useDirection(); - const { setToken } = useUser(); // pass token to set token - - // gettin url query - const searchParams = useSearchParams(); - const backUrlDecodedPath = searchParams.get("back_url"); - - // formik properties -// const handleSubmit = async (values, props) => { -// await axios -// .post(GET_USER_TOKEN, { -// username: values.username, -// password: values.password, -// }) -// .then(function (response) { -// setToken(response.data.token); -// }) -// .catch(function (error) { -// Notifications(directionApp, error.response, t); -// props.setSubmitting(false); -// }); -// }; - const initialValues = { - username: "", - password: "", - }; - const validationSchema = Yup.object().shape({ - username: Yup.string().required(t("LoginPage.error_message_required")), - password: Yup.string().required(t("LoginPage.error_message_required")), - }); - - return ( - - - - - - {(props) => ( - - - {t("app_name")} - - - {t("login_navy")} - - - - - - - - - - {t("LoginPage.button_make_account")} - - - - - - )} - - - - - - - {t("LoginPage.link_routing_back_to")}{" "} - {backUrlDecodedPath - ? t("LoginPage.link_routing_previuos_page") - : t("LoginPage.link_routing_main_page")} - - - - ); -}; - -export default LoginComponent; diff --git a/src/components/login-welfare-services/index.jsx b/src/components/login-welfare-services/index.jsx deleted file mode 100644 index 863f3aa..0000000 --- a/src/components/login-welfare-services/index.jsx +++ /dev/null @@ -1,170 +0,0 @@ -import LinkRouting from "@/core/components/LinkRouting"; -// import Notifications from "@/core/components/notifications"; -import PasswordField from "@/core/components/PasswordField"; -import StyledForm from "@/core/components/StyledForm"; -// import { GET_USER_TOKEN } from "@/core/data/apiRoutes"; -import CenterLayout from "@/layouts/CenterLayout"; -import FullPageLayout from "@/layouts/FullPageLayout"; -import useDirection from "@/lib/app/hooks/useDirection"; -import useUser from "@/lib/app/hooks/useUser"; -import LoginIcon from "@mui/icons-material/Login"; -import PersonAddIcon from "@mui/icons-material/PersonAdd"; -import { - Box, - Button, - Container, - Paper, - Stack, - TextField, - Typography, -} from "@mui/material"; -// import axios from "axios"; -import { Field, Formik } from "formik"; -import { useTranslations } from "next-intl"; -import Image from "next/image"; -import { useSearchParams } from "next/navigation"; -import * as Yup from "yup"; - -const LoginComponent = () => { - const t = useTranslations(); - const { directionApp } = useDirection(); - const { setToken } = useUser(); // pass token to set token - - // gettin url query - const searchParams = useSearchParams(); - const backUrlDecodedPath = searchParams.get("back_url"); - - // formik properties - // const handleSubmit = async (values, props) => { - // await axios - // .post(GET_USER_TOKEN, { - // username: values.username, - // password: values.password, - // }) - // .then(function (response) { - // setToken(response.data.token); - // }) - // .catch(function (error) { - // Notifications(directionApp, error.response, t); - // props.setSubmitting(false); - // }); - // }; - const initialValues = { - username: "", - password: "", - }; - const validationSchema = Yup.object().shape({ - username: Yup.string().required(t("LoginPage.error_message_required")), - password: Yup.string().required(t("LoginPage.error_message_required")), - }); - - return ( - - - - - - {(props) => ( - - - {t("app_name")} - - - {t("login_welfare_services")} - - - - - - - - - - - - - - - )} - - - - - - - {t("LoginPage.link_routing_back_to")}{" "} - {backUrlDecodedPath - ? t("LoginPage.link_routing_previuos_page") - : t("LoginPage.link_routing_main_page")} - - - - ); -}; - -export default LoginComponent; diff --git a/src/components/login/SendToken.jsx b/src/components/login/SendToken.jsx new file mode 100644 index 0000000..517a5db --- /dev/null +++ b/src/components/login/SendToken.jsx @@ -0,0 +1,147 @@ +import ResendToken from "@/core/components/ResendToken"; +import StyledForm from "@/core/components/StyledForm"; +import {LOGIN} from "@/core/data/apiRoutes"; +import CenterLayout from "@/layouts/CenterLayout"; +import FullPageLayout from "@/layouts/FullPageLayout"; +import useUser from "@/lib/app/hooks/useUser"; +import ChangeCircleIcon from "@mui/icons-material/ChangeCircle"; +import LoginIcon from "@mui/icons-material/Login"; +import {Box, Button, Container, Grid, Paper, Stack, TextField, Typography,} from "@mui/material"; +import {Field, Formik} from "formik"; +import {useTranslations} from "next-intl"; +import * as Yup from "yup"; +import SvgLogin from "@/core/components/svgs/SvgLogin"; +import useRequest from "@/lib/app/hooks/useRequest"; + +const SendTokenComponent = ({ + PhoneNumber, + setOtpToken, + timer, + setTimer, + initialTimerValue, + }) => { + const t = useTranslations(); + const requestServer = useRequest(); + const {setToken} = useUser(); + + const initialValues = { + phone_number: PhoneNumber, + verification_code: "", + }; + const validationSchema = Yup.object().shape({ + verification_code: Yup.string().required( + t("LoginPage.error_message_verification_code") + ), + }); + + const handleSubmit = (values, props) => { + requestServer(LOGIN, "post", { + auth: false, data: { + phone_number: values.phone_number, + verification_code: values.verification_code, + } + }) + .then(function (response) { + setToken(response.data.token); + }).catch(function (error) { + props.setSubmitting(false); + }); + }; + + return ( + + + + + + {(props) => ( + + + + + + {t("login")} + + + + + + {t("LoginPage.sent_token_to")}: {PhoneNumber} + + + + + + + + + + + + + + )} + + + + + + ); +}; + +export default SendTokenComponent; diff --git a/src/components/login/SendUserData.jsx b/src/components/login/SendUserData.jsx new file mode 100644 index 0000000..6743799 --- /dev/null +++ b/src/components/login/SendUserData.jsx @@ -0,0 +1,152 @@ +import LinkRouting from "@/core/components/LinkRouting"; +import StyledForm from "@/core/components/StyledForm"; +import {SEND_OTP_TOKEN} from "@/core/data/apiRoutes"; +import CenterLayout from "@/layouts/CenterLayout"; +import FullPageLayout from "@/layouts/FullPageLayout"; +import FingerprintIcon from "@mui/icons-material/Fingerprint"; +import PersonAddIcon from "@mui/icons-material/PersonAdd"; +import {Button, Container, Grid, Paper, Stack, TextField, Typography,} from "@mui/material"; +import {Field, Formik} from "formik"; +import {useTranslations} from "next-intl"; +import {useSearchParams} from "next/navigation"; +import * as Yup from "yup"; +import SvgLogin from "@/core/components/svgs/SvgLogin"; +import useRequest from "@/lib/app/hooks/useRequest"; + +const SendUserDataComponent = ({ + setOtpToken, + setPhoneNumber, + PhoneNumber, + setTimer, + initialTimerValue, + }) => { + const t = useTranslations(); + const requestServer = useRequest(); + + const searchParams = useSearchParams(); + const backUrlDecodedPath = searchParams.get("back_url"); + + const initialValues = { + phone_number: PhoneNumber, + }; + const validationSchema = Yup.object().shape({ + phone_number: Yup.string().required(t("LoginPage.error_message_phone_number")), + }); + + const handleSubmit = (values, props) => { + requestServer(SEND_OTP_TOKEN, "post", { + auth: false, data: { + phone_number: values.phone_number, + } + }) + .then(function (response) { + setPhoneNumber(values.phone_number); + setOtpToken(true); + setTimer(initialTimerValue); + }).catch(function (error) { + props.setSubmitting(false); + }); + }; + + return ( + + + + + + {(props) => ( + + + + + + {t("Titles.title_login_page")} + + + + + + + + + + + + + + + + + + )} + + + + + + + {t("LoginPage.link_routing_back_to")}{" "} + {backUrlDecodedPath + ? t("LoginPage.link_routing_previuos_page") + : t("LoginPage.link_routing_main_page")} + + + + ); +}; + +export default SendUserDataComponent; diff --git a/src/components/login/index.jsx b/src/components/login/index.jsx new file mode 100644 index 0000000..deaa2cc --- /dev/null +++ b/src/components/login/index.jsx @@ -0,0 +1,37 @@ +import {useState} from "react"; +import SendTokenComponent from "./SendToken"; +import SendUserDataComponent from "./SendUserData"; + +const LoginComponent = () => { + const [otpToken, setOtpToken] = useState(false); + const [PhoneNumber, setPhoneNumber] = useState(""); + + // For Resend Token (read ResendToken Component Doc) + const initialTimerValue = 30; + const [timer, setTimer] = useState(initialTimerValue); + // End For Resend Token + + if (!otpToken) { + return ( + + ); + } else { + return ( + + ); + } +}; + +export default LoginComponent; diff --git a/src/components/register-navy/index.jsx b/src/components/register-navy/index.jsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/components/register-welfare-services/index.jsx b/src/components/register-welfare-services/index.jsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/components/register/RequestOtp.jsx b/src/components/register/RequestOtp.jsx new file mode 100644 index 0000000..a24aa4f --- /dev/null +++ b/src/components/register/RequestOtp.jsx @@ -0,0 +1,131 @@ +import LinkRouting from "@/core/components/LinkRouting"; +import StyledForm from "@/core/components/StyledForm"; +import {SEND_OTP_TOKEN} from "@/core/data/apiRoutes"; +import CenterLayout from "@/layouts/CenterLayout"; +import FullPageLayout from "@/layouts/FullPageLayout"; +import FingerprintIcon from "@mui/icons-material/Fingerprint"; +import {Button, Container, Paper, Stack, TextField, Typography,} from "@mui/material"; +import {Field, Formik} from "formik"; +import {useTranslations} from "next-intl"; +import {useSearchParams} from "next/navigation"; +import * as Yup from "yup"; +import SvgLogin from "@/core/components/svgs/SvgLogin"; +import useRequest from "@/lib/app/hooks/useRequest"; + +const RequestOtpComponent = ({ + setOtpToken, + setPhoneNumber, + PhoneNumber, + setTimer, + initialTimerValue, + }) => { + const t = useTranslations(); + const requestServer = useRequest(); + + const searchParams = useSearchParams(); + const backUrlDecodedPath = searchParams.get("back_url"); + + const initialValues = { + phone_number: PhoneNumber, + }; + const validationSchema = Yup.object().shape({ + phone_number: Yup.string().required( + t("RegisterPage.error_message_phone_number") + ), + }); + + const handleSubmit = (values, props) => { + requestServer(SEND_OTP_TOKEN, "post", { + auth: false, data: { + phone_number: values.phone_number, + } + }) + .then(function (response) { + setPhoneNumber(values.phone_number); + setOtpToken(true); + setTimer(initialTimerValue); + }).catch(function (error) { + props.setSubmitting(false); + }); + }; + + return ( + + + + + + {(props) => ( + + + + + + {t("Titles.title_register_page")} + + + + + + + + + )} + + + + + + + {t("RegisterPage.link_routing_back_to")}{" "} + {backUrlDecodedPath + ? t("RegisterPage.link_routing_previuos_page") + : t("RegisterPage.link_routing_register")} + + + + ); +}; + +export default RequestOtpComponent; diff --git a/src/components/register/index.jsx b/src/components/register/index.jsx new file mode 100644 index 0000000..6e6b07d --- /dev/null +++ b/src/components/register/index.jsx @@ -0,0 +1,90 @@ +import LinkRouting, {NextLinkComposed} from "@/core/components/LinkRouting"; +import CenterLayout from "@/layouts/CenterLayout"; +import FullPageLayout from "@/layouts/FullPageLayout"; +import useUser from "@/lib/app/hooks/useUser"; +import {Box, Button, Grid, Stack} from "@mui/material"; +import {useTranslations} from "next-intl"; +import {useSearchParams} from "next/navigation"; +import SvgDashboard from "@/core/components/svgs/SvgDashboard"; + +const RegisterComponent = () => { + const t = useTranslations(); + const {isAuth} = useUser(); + + const searchParams = useSearchParams(); + const backUrlDecodedPath = searchParams.get("back_url"); + + return ( + + + + {isAuth ? ( + + ) : ( + + + + + + + + + + + )} + + + + {t("RegisterPage.link_routing_back_to")}{" "} + {backUrlDecodedPath + ? t("RegisterPage.link_routing_previuos_page") + : t("RegisterPage.link_routing_login")} + + + + ); +}; + +export default RegisterComponent; diff --git a/src/components/register/navy/UserRegister.jsx b/src/components/register/navy/UserRegister.jsx new file mode 100644 index 0000000..09346cc --- /dev/null +++ b/src/components/register/navy/UserRegister.jsx @@ -0,0 +1,195 @@ +import StyledForm from "@/core/components/StyledForm"; +import {REGISTER} from "@/core/data/apiRoutes"; +import CenterLayout from "@/layouts/CenterLayout"; +import FullPageLayout from "@/layouts/FullPageLayout"; +import LoginIcon from "@mui/icons-material/Login"; +import ChangeCircleIcon from "@mui/icons-material/ChangeCircle"; +import {Box, Button, Chip, Container, Divider, Paper, Stack, TextField, Typography,} from "@mui/material"; +import {Field, Formik} from "formik"; +import {useTranslations} from "next-intl"; +import * as Yup from "yup"; +import ResendToken from "@/core/components/ResendToken"; +import useUser from "@/lib/app/hooks/useUser"; +import SvgRegister from "@/core/components/svgs/SvgRegister"; +import useRequest from "@/lib/app/hooks/useRequest"; + +const UserRegisterComponent = ({ + PhoneNumber, + setOtpToken, + initialTimerValue, + timer, + setTimer, + }) => { + const t = useTranslations(); + const {setToken} = useUser(); + const requestServer = useRequest(); + + const initialValues = { + type_id: "1", + verification_code: "", + phone_number: PhoneNumber, + national_id: "", + navgan_id: "", + }; + + const validationSchema = Yup.object().shape({ + verification_code: Yup.string().required( + t("RegisterPage.error_message_verification_code") + ), + national_id: Yup.string().required( + t("RegisterPage.error_message_national_id") + ), + navgan_id: Yup.string().required(t("RegisterPage.error_message_navgan_id")), + }); + + const handleSubmit = (values, props) => { + requestServer(REGISTER, "post", { + auth: false, data: { + type_id: values.type_id, + national_id: values.national_id, + navgan_id: values.navgan_id, + phone_number: values.phone_number, + verification_code: values.verification_code, + } + }) + .then(function (response) { + setOtpToken(true); + setToken(response.data.token); + }).catch(function (error) { + props.setSubmitting(false); + }); + }; + + return ( + + + + + + {(props) => ( + + + + + + {t("register_navy")} + + + + + + {t("LoginPage.sent_token_to")}: {PhoneNumber} + + + + + + + + + + + + + + + )} + + + + + + ); +}; + +export default UserRegisterComponent; diff --git a/src/components/register/navy/index.jsx b/src/components/register/navy/index.jsx new file mode 100644 index 0000000..9296f78 --- /dev/null +++ b/src/components/register/navy/index.jsx @@ -0,0 +1,37 @@ +import {useState} from "react"; +import RequestOtpComponent from "../RequestOtp"; +import UserRegisterComponent from "./UserRegister"; + +const NavyComponent = () => { + const [otpToken, setOtpToken] = useState(false); + const [PhoneNumber, setPhoneNumber] = useState(""); + + // For Resend Token (read ResendToken Component Doc) + const initialTimerValue = 30; + const [timer, setTimer] = useState(initialTimerValue); + // End For Resend Token + + if (!otpToken) { + return ( + + ); + } else { + return ( + + ); + } +}; + +export default NavyComponent; diff --git a/src/components/register/welfare-services/UserRegister.jsx b/src/components/register/welfare-services/UserRegister.jsx new file mode 100644 index 0000000..a043a53 --- /dev/null +++ b/src/components/register/welfare-services/UserRegister.jsx @@ -0,0 +1,174 @@ +import StyledForm from "@/core/components/StyledForm"; +import {REGISTER} from "@/core/data/apiRoutes"; +import CenterLayout from "@/layouts/CenterLayout"; +import FullPageLayout from "@/layouts/FullPageLayout"; +import LoginIcon from "@mui/icons-material/Login"; +import ChangeCircleIcon from "@mui/icons-material/ChangeCircle"; +import {Box, Button, Chip, Container, Divider, Paper, Stack, TextField, Typography,} from "@mui/material"; +import {Field, Formik} from "formik"; +import {useTranslations} from "next-intl"; +import * as Yup from "yup"; +import ResendToken from "@/core/components/ResendToken"; +import useUser from "@/lib/app/hooks/useUser"; +import SvgRegister from "@/core/components/svgs/SvgRegister"; +import useRequest from "@/lib/app/hooks/useRequest"; + +const UserRegisterComponent = ({ + PhoneNumber, + setOtpToken, + initialTimerValue, + timer, + setTimer, + }) => { + const t = useTranslations(); + const {setToken} = useUser(); + const requestServer = useRequest(); + + const initialValues = { + type_id: "2", + verification_code: "", + phone_number: PhoneNumber, + national_id: "", + }; + + const validationSchema = Yup.object().shape({ + verification_code: Yup.string().required( + t("RegisterPage.error_message_verification_code") + ), + national_id: Yup.string().required( + t("RegisterPage.error_message_national_id") + ), + }); + + const handleSubmit = (values, props) => { + requestServer(REGISTER, "post", { + auth: false, data: { + type_id: values.type_id, + national_id: values.national_id, + phone_number: values.phone_number, + verification_code: values.verification_code, + } + }) + .then(function (response) { + setOtpToken(true); + setToken(response.data.token); + }).catch(function (error) { + props.setSubmitting(false); + }); + }; + + return ( + + + + + + {(props) => ( + + + + + + {t("register_welfare_services")} + + + + + + {t("LoginPage.sent_token_to")}: {PhoneNumber} + + + + + + + + + + + + + + )} + + + + + + ); +}; + +export default UserRegisterComponent; diff --git a/src/components/register/welfare-services/index.jsx b/src/components/register/welfare-services/index.jsx new file mode 100644 index 0000000..322490f --- /dev/null +++ b/src/components/register/welfare-services/index.jsx @@ -0,0 +1,37 @@ +import {useState} from "react"; +import RequestOtpComponent from "../RequestOtp"; +import UserRegisterComponent from "./UserRegister"; + +const WelfareServicesComponent = () => { + const [otpToken, setOtpToken] = useState(false); + const [PhoneNumber, setPhoneNumber] = useState(""); + + // For Resend Token (read ResendToken Component Doc) + const initialTimerValue = 30; + const [timer, setTimer] = useState(initialTimerValue); + // End For Resend Token + + if (!otpToken) { + return ( + + ); + } else { + return ( + + ); + } +}; + +export default WelfareServicesComponent; diff --git a/src/core/components/LinkRouting.jsx b/src/core/components/LinkRouting.jsx index ff33c86..f8fac0a 100644 --- a/src/core/components/LinkRouting.jsx +++ b/src/core/components/LinkRouting.jsx @@ -1,116 +1,116 @@ import MuiLink from "@mui/material/Link"; -import { styled } from "@mui/material/styles"; +import {styled} from "@mui/material/styles"; import clsx from "clsx"; import NextLink from "next/link"; -import { useRouter } from "next/router"; +import {useRouter} from "next/router"; import * as React from "react"; // Add support for the sx prop for consistency with the other branches. const Anchor = styled("a")({}); export const NextLinkComposed = React.forwardRef(function NextLinkComposed( - props, - ref + props, + ref ) { - const { - to, - linkAs, - replace, - scroll, - shallow, - prefetch, - legacyBehavior = true, - locale, - ...other - } = props; + const { + to, + linkAs, + replace, + scroll, + shallow, + prefetch, + legacyBehavior = true, + locale, + ...other + } = props; - return ( - - - - ); + return ( + + + + ); }); // A styled version of the Next.js Link component: // https://nextjs.org/docs/api-reference/next/link const LinkRouting = React.forwardRef(function Link(props, ref) { - const { - activeClassName = "active", - as, - className: classNameProps, - href, - legacyBehavior, - linkAs: linkAsProp, - locale, - noLinkStyle, - prefetch, - replace, - role, // Link don't have roles. - scroll, - shallow, - ...other - } = props; + const { + activeClassName = "active", + as, + className: classNameProps, + href, + legacyBehavior, + linkAs: linkAsProp, + locale, + noLinkStyle, + prefetch, + replace, + role, // Link don't have roles. + scroll, + shallow, + ...other + } = props; - const router = useRouter(); - const pathname = typeof href === "string" ? href : href.pathname; - const className = clsx(classNameProps, { - [activeClassName]: router.pathname === pathname && activeClassName, - }); + const router = useRouter(); + const pathname = typeof href === "string" ? href : href.pathname; + const className = clsx(classNameProps, { + [activeClassName]: router.pathname === pathname && activeClassName, + }); - const isExternal = - typeof href === "string" && - (href.indexOf("http") === 0 || href.indexOf("mailto:") === 0); + const isExternal = + typeof href === "string" && + (href.indexOf("http") === 0 || href.indexOf("mailto:") === 0); - if (isExternal) { - if (noLinkStyle) { - return ; + if (isExternal) { + if (noLinkStyle) { + return ; + } + + return ; } - return ; - } + const linkAs = linkAsProp || as; + const nextjsProps = { + to: href, + linkAs, + replace, + scroll, + shallow, + prefetch, + legacyBehavior, + locale, + }; - const linkAs = linkAsProp || as; - const nextjsProps = { - to: href, - linkAs, - replace, - scroll, - shallow, - prefetch, - legacyBehavior, - locale, - }; + if (noLinkStyle) { + return ( + + ); + } - if (noLinkStyle) { return ( - + ); - } - - return ( - - ); }); export default LinkRouting; diff --git a/src/core/components/LoadingHardPage.jsx b/src/core/components/LoadingHardPage.jsx index 5da632d..3f558cd 100644 --- a/src/core/components/LoadingHardPage.jsx +++ b/src/core/components/LoadingHardPage.jsx @@ -1,44 +1,44 @@ -import { Backdrop, Fade, styled } from "@mui/material"; -import StyledImage from "./StyledImage"; +import {Backdrop, Box, Fade, styled} from "@mui/material"; +import SvgLoading from "@/core/components/svgs/SvgLoading"; -const LoadingImage = styled(StyledImage)({ - "@keyframes load": { - "0%": { - // opacity: 0, - transform: "scale(1)", +const LoadingImage = styled(Box)({ + "@keyframes load": { + "0%": { + // opacity: 0, + transform: "scale(1)", + }, + "50%": { + // opacity: 1, + transform: "scale(2)", + }, + "100%": { + // opacity: 0, + transform: "scale(1)", + }, }, - "50%": { - // opacity: 1, - transform: "scale(2)", - }, - "100%": { - // opacity: 0, - transform: "scale(1)", - }, - }, - animation: "load 2s infinite", + animation: "load 2s infinite", }); -const LoadingHardPage = ({ children, loading }) => { - return ( - <> - theme.zIndex.drawer + 1 }} - open={loading} - > - - - - - {children} - - ); +const LoadingHardPage = ({children, loading}) => { + return ( + <> + theme.zIndex.drawer + 1}} + open={loading} + > + + + + + + + {children} + + ); }; export default LoadingHardPage; diff --git a/src/core/components/Messages.jsx b/src/core/components/Messages.jsx index ea9cd29..8a5cfc9 100644 --- a/src/core/components/Messages.jsx +++ b/src/core/components/Messages.jsx @@ -1,22 +1,18 @@ import CenterLayout from "@/layouts/CenterLayout"; import FullPageLayout from "@/layouts/FullPageLayout"; -import StyledImage from "./StyledImage"; +import SvgLoading from "@/core/components/svgs/SvgLoading"; -const Message = ({ text, actions }) => { - return ( - - - - {text} - {actions} - - - ); +const Message = ({text, actions}) => { + return ( + + + + {text} + {actions} + + + ); }; export default Message; diff --git a/src/core/components/NoSsrHandler.jsx b/src/core/components/NoSsrHandler.jsx new file mode 100644 index 0000000..5a4c4e1 --- /dev/null +++ b/src/core/components/NoSsrHandler.jsx @@ -0,0 +1,8 @@ +import {NoSsr} from "@mui/material"; + +const NoSsrHandler = ({isBot, children}) => { + if (isBot) return children; + return {children}; +}; + +export default NoSsrHandler; diff --git a/src/core/components/PasswordField.jsx b/src/core/components/PasswordField.jsx index 5747bdb..d109b73 100644 --- a/src/core/components/PasswordField.jsx +++ b/src/core/components/PasswordField.jsx @@ -1,33 +1,33 @@ -import { useState } from "react"; -import { IconButton, InputAdornment, TextField } from "@mui/material"; -import { Visibility, VisibilityOff } from "@mui/icons-material"; -import { Field } from "formik"; +import {useState} from "react"; +import {IconButton, InputAdornment, TextField} from "@mui/material"; +import {Visibility, VisibilityOff} from "@mui/icons-material"; +import {Field} from "formik"; const PasswordField = (props) => { - const [showPassword, setShowPassword] = useState(false); + const [showPassword, setShowPassword] = useState(false); - const handleClickShowPassword = () => { - setShowPassword(!showPassword); - }; + const handleClickShowPassword = () => { + setShowPassword(!showPassword); + }; - return ( - - - {showPassword ? : } - - - ), - }} - /> - ); + return ( + + + {showPassword ? : } + + + ), + }} + /> + ); }; export default PasswordField; diff --git a/src/core/components/ResendToken.jsx b/src/core/components/ResendToken.jsx new file mode 100644 index 0000000..906581c --- /dev/null +++ b/src/core/components/ResendToken.jsx @@ -0,0 +1,78 @@ +import Notifications from "@/core/components/notifications"; +import useDirection from "@/lib/app/hooks/useDirection"; +import {Button} from "@mui/material"; +import axios from "axios"; +import {useTranslations} from "next-intl"; +import {useEffect} from "react"; +import {LOGIN, SEND_OTP_TOKEN} from "../data/apiRoutes"; +import useRequest from "@/lib/app/hooks/useRequest"; + +const ResendToken = ({initialTimerValue, timer, setTimer, PhoneNumber, disabled}) => { + const t = useTranslations(); + const {directionApp} = useDirection(); + const requestServer = useRequest(); + // Countdown Timer + useEffect(() => { + let interval; + if (timer > 0) { + interval = setInterval(() => { + setTimer((prevTimer) => prevTimer - 1); + }, 1000); + } else { + clearInterval(interval); + } + + return () => clearInterval(interval); + }, [timer]); + // End Countdown Timer + + // Handle Resend Token + const handleResendClick = () => { + if (timer != 0) return; + requestServer(SEND_OTP_TOKEN, "post", { + auth: false, data: { + phone_number: PhoneNumber, + } + }) + .then(function (response) { + setTimer(initialTimerValue); + }).catch(function (error) { + }); + }; + // End Handle Resend Token + + return ( + <> + {timer > 0 ? ( + + ) : ( + + )} + + ); +}; + +export default ResendToken; + +//////****** usage document ******///////// +// 1.) use component inside your page +// 2.) list of props that you need to send is down below +// 2.1) initialTimerValue **** Delay Time For Sending Token +// 2.2) timer **** Timer Of Resending Token +// 2.3) setTimer **** Set Timer Of Resend (note: every places in your components if you are requesting for getting token you should use this prop like this setTimer(initialTimerValue) ) +// 2.4) PhoneNumber **** Phone Number That Should Recive Token diff --git a/src/core/components/SelectBox.jsx b/src/core/components/SelectBox.jsx new file mode 100644 index 0000000..a24484c --- /dev/null +++ b/src/core/components/SelectBox.jsx @@ -0,0 +1,52 @@ +import {FormControl, FormHelperText, InputLabel, MenuItem, Select,} from "@mui/material"; + +function SelectBox({ + select, + selectType, + selectors, + label, + setFieldValue, + setFieldTouched, + error, + helperText, + }) { + + const selectId = String(select); + const handleChange = (event) => { + setFieldValue(selectType, event.target.value); + }; + const handleBlur = () => { + setFieldTouched(select, true); + }; + return ( + + {label} + + {helperText} + + ); +} + +export default SelectBox; diff --git a/src/core/components/StyledForm.jsx b/src/core/components/StyledForm.jsx index 1f299bb..41eeabc 100644 --- a/src/core/components/StyledForm.jsx +++ b/src/core/components/StyledForm.jsx @@ -1,5 +1,5 @@ -import { styled } from "@mui/material"; -import { Form } from "formik"; +import {styled} from "@mui/material"; +import {Form} from "formik"; const StyledForm = styled(Form)``; diff --git a/src/core/components/StyledImage.jsx b/src/core/components/StyledImage.jsx index 64391ad..58dd65f 100644 --- a/src/core/components/StyledImage.jsx +++ b/src/core/components/StyledImage.jsx @@ -1,4 +1,4 @@ -import { styled } from "@mui/material"; +import {styled} from "@mui/material"; import Image from "next/image"; const StyledImage = styled(Image)``; diff --git a/src/core/components/TitlePage.jsx b/src/core/components/TitlePage.jsx index 7bdcfc2..77c72ee 100644 --- a/src/core/components/TitlePage.jsx +++ b/src/core/components/TitlePage.jsx @@ -1,15 +1,15 @@ -import { useTranslations } from "next-intl"; +import {useTranslations} from "next-intl"; import Head from "next/head"; -const TitlePage = ({ text }) => { - const t = useTranslations(); - return ( - - - {text ? `${t("app_short_name")} | ${t(text)}` : t("app_short_name")} - - - ); +const TitlePage = ({text}) => { + const t = useTranslations(); + return ( + + + {text ? `${t("app_short_name")} | ${t(text)}` : t("app_short_name")} + + + ); }; export default TitlePage; diff --git a/src/core/components/UploadSystem.jsx b/src/core/components/UploadSystem.jsx new file mode 100644 index 0000000..54dd49d --- /dev/null +++ b/src/core/components/UploadSystem.jsx @@ -0,0 +1,152 @@ +import {Box, Button, FormHelperText, TextField, Typography} from "@mui/material"; +import {useTranslations} from "next-intl"; +import Image from "next/image"; +import DeleteForeverIcon from "@mui/icons-material/DeleteForever"; +import {useRef, useState} from "react"; + +const UploadSystem = ({ + fieldName, + default_image, + helperText, + error, + setFieldValue, + imageAlt, + label, + enableDelete + }) => { + const t = useTranslations(); + const fileInputRef = useRef(null); + const [selectedImage, setSelectedImage] = useState(default_image || "/images/upload-image.svg"); + const [fileType, setFileType] = useState(null); + const [fileName, setFileName] = useState(""); + + // upload files + const handleUploadChange = (event) => { + const uploadedFile = event.target?.files?.[0]; + if (uploadedFile) { + setSelectedImage(URL.createObjectURL(uploadedFile)); + setFileType(uploadedFile.type); + setFileName(uploadedFile.name); + setFieldValue(fieldName, uploadedFile); + } + }; + // end upload files + + const uploadBoxStyle = error ? { + cursor: "pointer", + objectFit: "contain", + border: "1px dashed #d32f2f", + borderRadius: "5px", + padding: "5px", + } : { + cursor: "pointer", + objectFit: "contain", + border: "1px dashed #e1e1e1", + borderRadius: "5px", + padding: "5px", + } + + const handleClick = () => { + fileInputRef.current.click(); + }; + const handleDeleteImage = () => { + setselectedImage("/images/upload-image.svg"); + setFieldValue(fieldname, null); + }; + + return ( + + + {label} + + + + + {selectedImage === "/images/upload-image.svg" || selectedImage === default_image ? ( + {imageAlt} + ) : fileType && fileType.startsWith("image/") ? ( + {imageAlt} + ) : ( + + + {fileName} + + + )} + + handleUploadChange(e)} + inputRef={fileInputRef} + /> + {enableDelete ? : ""} + {helperText} + + ); +}; + +export default UploadSystem; diff --git a/src/core/components/isBotHandler.jsx b/src/core/components/isBotHandler.jsx deleted file mode 100644 index 0fde3e3..0000000 --- a/src/core/components/isBotHandler.jsx +++ /dev/null @@ -1,8 +0,0 @@ -import { NoSsr } from "@mui/material"; - -const NoSsrHandler = ({ isBot, children }) => { - if (isBot) return children; - return {children}; -}; - -export default NoSsrHandler; diff --git a/src/core/components/notifications/ErrorNotification.jsx b/src/core/components/notifications/ErrorNotification.jsx new file mode 100644 index 0000000..4c2e857 --- /dev/null +++ b/src/core/components/notifications/ErrorNotification.jsx @@ -0,0 +1,39 @@ +import DangerousIcon from "@mui/icons-material/Dangerous"; +import {Box, Typography} from "@mui/material"; +import {toast} from "react-toastify"; + +const ErrorNotification = (t, status, message) => { + toast( + ({closeToast}) => ( + <> + + + + + + {t("notifications.error")} ({t("notifications.code")}: {status}) + + + {message || t("notifications.error_static_text")} + + + + + + ), + { + autoClose: false, + closeOnClick: false, + draggable: false, + } + ); +}; + +export default ErrorNotification; diff --git a/src/core/components/notifications/PendingNotification.jsx b/src/core/components/notifications/PendingNotification.jsx new file mode 100644 index 0000000..f3a0af4 --- /dev/null +++ b/src/core/components/notifications/PendingNotification.jsx @@ -0,0 +1,11 @@ +import {toast} from "react-toastify"; + +const PendingNotification = (t) => { + toast(t("notifications.pending"), { + autoClose: false, + closeOnClick: false, + draggable: false, + }); +}; + +export default PendingNotification; diff --git a/src/core/components/notifications/SuccessNotification.jsx b/src/core/components/notifications/SuccessNotification.jsx new file mode 100644 index 0000000..998deaa --- /dev/null +++ b/src/core/components/notifications/SuccessNotification.jsx @@ -0,0 +1,42 @@ +import BeenhereIcon from "@mui/icons-material/Beenhere"; +import {Box, Typography} from "@mui/material"; +import {toast} from "react-toastify"; + +const SuccessNotification = (t, status) => { + toast( + () => ( + <> + + + + + + {t("notifications.success")} ({t("notifications.code")}:{" "} + {status}) + + + {t("notifications.success_static_text")} + + + + + + ), + { + autoClose: 3000, + hideProgressBar: true, + pauseOnHover: true, + closeOnClick: false, + draggable: true, + } + ); +}; + +export default SuccessNotification; diff --git a/src/core/components/notifications/WarningNotification.jsx b/src/core/components/notifications/WarningNotification.jsx new file mode 100644 index 0000000..5e931f0 --- /dev/null +++ b/src/core/components/notifications/WarningNotification.jsx @@ -0,0 +1,40 @@ +import ReportIcon from "@mui/icons-material/Report"; +import {Box, Divider, Typography} from "@mui/material"; +import {toast} from "react-toastify"; + +const WarningNotification = (t, status) => { + toast( + ({closeToast}) => ( + <> + + + + + + {t("warning")} ({t("code")}: {status}) + + + {t("warning_static_text")} + + + + + + + ), + { + autoClose: false, + closeOnClick: false, + draggable: false, + } + ); +}; + +export default WarningNotification; diff --git a/src/core/components/notifications/index.jsx b/src/core/components/notifications/index.jsx new file mode 100644 index 0000000..9425aef --- /dev/null +++ b/src/core/components/notifications/index.jsx @@ -0,0 +1,54 @@ +import {toast} from "react-toastify"; +import ErrorNotification from "./ErrorNotification"; +import SuccessNotification from "./SuccessNotification"; +import WarningNotification from "./WarningNotification"; + +const Notifications = async (t, response) => { + const {status, data} = response != undefined ? response : "" + toast.dismiss(); + switch (status) { + case 200: + SuccessNotification(t, status); + break; + case 400: + ErrorNotification(t, status); + break; + case 401: + ErrorNotification(t, status); + break; + case 403: + ErrorNotification(t, status); + break; + case 422: + ErrorNotification(t, status, data.message); + break; + case 500: + WarningNotification(t, status); + break; + case 503: + WarningNotification(t, status); + break; + case 504: + WarningNotification(t, status); + break; + default: + toast(t("pending"), { + autoClose: false, + closeOnClick: false, + draggable: false, + }); + break; + } +}; + +export default Notifications; + +/* +usage document + +** for pending use ( Notifications( t, undefined) ) this before your request. +** for success use ( Notifications( t, response) ) this inside .then() of your request. +** for Error and Warning use ( Notifications( t, error.response) ) this inside .catche() of your request. + +end usage document +*/ diff --git a/src/core/components/svgs/Svg403.jsx b/src/core/components/svgs/Svg403.jsx new file mode 100644 index 0000000..720828c --- /dev/null +++ b/src/core/components/svgs/Svg403.jsx @@ -0,0 +1,131 @@ +import {useTheme} from "@mui/material"; + +const Svg403 = ({width, height}) => { + const theme = useTheme() + const fillColor = theme.palette.primary.main + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + +} + +export default Svg403 \ No newline at end of file diff --git a/src/core/components/svgs/Svg404.jsx b/src/core/components/svgs/Svg404.jsx new file mode 100644 index 0000000..e46ab12 --- /dev/null +++ b/src/core/components/svgs/Svg404.jsx @@ -0,0 +1,101 @@ +import {useTheme} from "@mui/material"; + +const Svg404 = ({width, height}) => { + const theme = useTheme() + const fillColor = theme.palette.primary.main + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} + +export default Svg404 \ No newline at end of file diff --git a/src/core/components/svgs/Svg500.jsx b/src/core/components/svgs/Svg500.jsx new file mode 100644 index 0000000..c9d92e8 --- /dev/null +++ b/src/core/components/svgs/Svg500.jsx @@ -0,0 +1,81 @@ +import {useTheme} from "@mui/material"; + +const Svg404 = ({width, height}) => { + const theme = useTheme() + const fillColor = theme.palette.primary.main + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} + +export default Svg404 \ No newline at end of file diff --git a/src/core/components/svgs/SvgDashboard.jsx b/src/core/components/svgs/SvgDashboard.jsx new file mode 100644 index 0000000..7dc48fc --- /dev/null +++ b/src/core/components/svgs/SvgDashboard.jsx @@ -0,0 +1,117 @@ +import {useTheme} from "@mui/material"; + +const SvgDashboard = ({width, height}) => { + const theme = useTheme() + const fillColor = theme.palette.primary.main + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} + +export default SvgDashboard \ No newline at end of file diff --git a/src/core/components/svgs/SvgLoading.jsx b/src/core/components/svgs/SvgLoading.jsx new file mode 100644 index 0000000..f9cea4a --- /dev/null +++ b/src/core/components/svgs/SvgLoading.jsx @@ -0,0 +1,136 @@ +import {useTheme} from "@mui/material"; + +const SvgLoading = ({width, height}) => { + const theme = useTheme() + const fillColor = theme.palette.primary.main + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} + +export default SvgLoading \ No newline at end of file diff --git a/src/core/components/svgs/SvgLogin.jsx b/src/core/components/svgs/SvgLogin.jsx new file mode 100644 index 0000000..643c195 --- /dev/null +++ b/src/core/components/svgs/SvgLogin.jsx @@ -0,0 +1,75 @@ +import {useTheme} from "@mui/material"; + +const SvgLogin = ({width, height}) => { + const theme = useTheme() + const fillColor = theme.palette.primary.main + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + +} + +export default SvgLogin \ No newline at end of file diff --git a/src/core/components/svgs/SvgRegister.jsx b/src/core/components/svgs/SvgRegister.jsx new file mode 100644 index 0000000..0a1dd06 --- /dev/null +++ b/src/core/components/svgs/SvgRegister.jsx @@ -0,0 +1,109 @@ +import {useTheme} from "@mui/material"; + +const SvgRegister = ({width, height}) => { + const theme = useTheme() + const fillColor = theme.palette.primary.main + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + +} + +export default SvgRegister \ No newline at end of file diff --git a/src/core/data/apiRoutes.js b/src/core/data/apiRoutes.js index e69de29..64cbc59 100644 --- a/src/core/data/apiRoutes.js +++ b/src/core/data/apiRoutes.js @@ -0,0 +1,17 @@ +const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL + "/api"; + +// export const LOGIN_SEND_OTP_TOKEN = BASE_URL + "/login/send_otp"; +export const LOGIN = BASE_URL + "/login"; +// export const REGISTER_SEND_OTP_TOKEN = BASE_URL + "/register/send_otp"; +export const SEND_OTP_TOKEN = BASE_URL + "/otp"; +export const REGISTER = BASE_URL + "/register"; +export const USER_INFO = BASE_URL + "/profile/info"; +export const SHOW_LOAN_REQUEST_NAVGAN = BASE_URL + "/navgan/loan/index"; +export const SEND_LOAN_REQUEST_NAVGAN = BASE_URL + "/navgan/loan/store"; +export const SHOW_LOAN_REQUEST_WELFARE = BASE_URL + "/refahi/loan/index"; +export const SEND_LOAN_REQUEST_WELFARE = BASE_URL + "/refahi/loan/store"; +export const UPDATE_LOAN_REQUEST_WELFARE = BASE_URL + "/refahi/loan/update/"; +export const DETAILS_LOAN_REQUEST_WELFARE = BASE_URL + "/refahi/loan/details/"; +export const GET_PROVINCE_LIST = BASE_URL + "/provinces"; + + diff --git a/src/core/data/headerProfileItems.jsx b/src/core/data/headerProfileItems.jsx index 63e661a..8164f38 100644 --- a/src/core/data/headerProfileItems.jsx +++ b/src/core/data/headerProfileItems.jsx @@ -1,19 +1,3 @@ -import BorderColorIcon from "@mui/icons-material/BorderColor"; -import PasswordIcon from "@mui/icons-material/Password"; - -const headerProfileItems = [ - { - key: 0, - name: "header.edit_profile", - route: "/dashboard/edit-profile", - icon: , - }, - { - key: 1, - name: "header.change_password", - route: "/dashboard/change-password", - icon: , - }, -]; +const headerProfileItems = []; export default headerProfileItems; diff --git a/src/core/data/sidebarMenu.jsx b/src/core/data/sidebarMenu.jsx index cc01fa6..a78ed6c 100644 --- a/src/core/data/sidebarMenu.jsx +++ b/src/core/data/sidebarMenu.jsx @@ -3,29 +3,53 @@ import BookmarkAddedIcon from "@mui/icons-material/BookmarkAdded"; import DataSaverOnIcon from "@mui/icons-material/DataSaverOn"; const sidebarMenu = [ - [ - { - key: "sidebar.dashboard", - type: "page", - route: "/dashboard", - icon: , - selected: false, - }, - { - key: "sidebar.loan-request", - type: "page", - route: "/dashboard/loan-request", - icon: , - selected: false, - }, - { - key: "sidebar.loan-follow-up", - type: "page", - route: "/dashboard/loan-follow-up", - icon: , - selected: false, - }, - ], + [ + { + key: "sidebar.dashboard", + type: "page", + route: "/dashboard", + icon: , + userType: 0, + selected: false, + permission_name: "all" + }, + { + key: "sidebar.add-request-loan", + type: "page", + route: "/dashboard/navgan/add-request-loan", + icon: , + userType: 1, + selected: false, + permission_name: "can_request_a_new_loan" + }, + { + key: "sidebar.followUp-loan", + type: "page", + route: "/dashboard/navgan/followUp-loan", + icon: , + userType: 1, + selected: false, + permission_name: "all" + }, + { + key: "sidebar.add-request-loan", + type: "page", + route: "/dashboard/refahi/add-request-loan", + icon: , + userType: 2, + selected: false, + permission_name: "can_request_a_new_loan" + }, + { + key: "sidebar.followUp-loan", + type: "page", + route: "/dashboard/refahi/followUp-loan", + icon: , + userType: 2, + selected: false, + permission_name: "all" + }, + ], ]; export default sidebarMenu; diff --git a/src/core/utils/createEmotionCache.jsx b/src/core/utils/createEmotionCache.jsx index 06add02..413fafe 100644 --- a/src/core/utils/createEmotionCache.jsx +++ b/src/core/utils/createEmotionCache.jsx @@ -1,38 +1,38 @@ import createCache from "@emotion/cache"; -import { prefixer } from "stylis"; +import {prefixer} from "stylis"; import stylisRTLPlugin from "stylis-plugin-rtl"; const isBrowser = typeof document !== "undefined"; export const createEmotionCacheLtr = () => { - let insertionPoint; + let insertionPoint; - if (isBrowser) { - const emotionInsertionPoint = document.querySelector( - 'meta[name="emotion-insertion-point"]' - ); - insertionPoint = emotionInsertionPoint ?? undefined; - } + if (isBrowser) { + const emotionInsertionPoint = document.querySelector( + 'meta[name="emotion-insertion-point"]' + ); + insertionPoint = emotionInsertionPoint ?? undefined; + } - return createCache({ - key: "mui-style", - insertionPoint, - }); + return createCache({ + key: "mui-style", + insertionPoint, + }); }; export const createEmotionCacheRtl = () => { - let insertionPoint; + let insertionPoint; - if (isBrowser) { - const emotionInsertionPoint = document.querySelector( - 'meta[name="emotion-insertion-point"]' - ); - insertionPoint = emotionInsertionPoint ?? undefined; - } + if (isBrowser) { + const emotionInsertionPoint = document.querySelector( + 'meta[name="emotion-insertion-point"]' + ); + insertionPoint = emotionInsertionPoint ?? undefined; + } - return createCache({ - key: "muirtl", - stylisPlugins: [prefixer, stylisRTLPlugin], - insertionPoint, - }); + return createCache({ + key: "muirtl", + stylisPlugins: [prefixer, stylisRTLPlugin], + insertionPoint, + }); }; diff --git a/src/core/utils/errorHandler.js b/src/core/utils/errorHandler.js new file mode 100644 index 0000000..ec5858a --- /dev/null +++ b/src/core/utils/errorHandler.js @@ -0,0 +1,62 @@ +import ErrorNotification from "@/core/components/notifications/ErrorNotification"; +import WarningNotification from "@/core/components/notifications/WarningNotification"; +import {toast} from "react-toastify"; + +export const errorSetting = (t, notification) => { + //todo +} + +export const errorRequest = (t, notification) => { + //todo +} + +export const errorResponse = (response, clearToken, t, notification) => { + if (notification) toast.dismiss(); + if (isServerError(response.status)) { + errorServer(response, t, notification) + } else if (isClientError(response.status)) { + errorClient(response, clearToken, t, notification) + } +} + +const errorServer = (response, t, notification) => { + if (notification) WarningNotification(t, response.status); +} +const errorClient = (response, clearToken, t, notification) => { + switch (response.status) { + case 401: + clearToken() + if (notification) ErrorNotification(t, response.status) + break; + case 422: + if ('type' in response.data) { + errorLogic(response, t, notification) + break; + } + errorValidation(response, t, notification) + break; + case 429: + if (notification) ErrorNotification(t, response.status) + break + default: + if (notification) ErrorNotification(t, response.status) + break + } +} + +const isServerError = status => status >= 500 && status <= 599; +const isClientError = status => status >= 400 && status <= 499; + +const errorLogic = (response, t, notification) => { + if (notification) ErrorNotification(t, response.status) +} +const errorValidation = (response, t, notification) => { + if (notification) { + const errorsMap = Object.keys(response.data.errors) + const errorsArray = response.data.errors + + errorsMap.map((item, index) => { + ErrorNotification(t, response.status, errorsArray[item][0]); + }) + } +} diff --git a/src/core/utils/succesHandler.js b/src/core/utils/succesHandler.js new file mode 100644 index 0000000..a61ac85 --- /dev/null +++ b/src/core/utils/succesHandler.js @@ -0,0 +1,9 @@ +import SuccessNotification from "@/core/components/notifications/SuccessNotification"; +import {toast} from "react-toastify"; + +export const successRequest = (response, t, options) => { + if (options.notification && options.success.notification.show) { + toast.dismiss(); + SuccessNotification(t, response.status) + } +} \ No newline at end of file diff --git a/src/core/utils/theme-rtl.jsx b/src/core/utils/theme-rtl.jsx index c36abeb..fb0bbaa 100644 --- a/src/core/utils/theme-rtl.jsx +++ b/src/core/utils/theme-rtl.jsx @@ -1,12 +1,12 @@ -import { createTheme } from "@mui/material/styles"; +import {createTheme} from "@mui/material/styles"; import theme from "./theme"; const themeRtl = createTheme({ - direction: "rtl", - typography: { - fontFamily: `IRANSans, sans-serif`, - }, - ...theme, + direction: "rtl", + typography: { + fontFamily: `IRANSansFaNum, sans-serif`, + }, + ...theme, }); export default themeRtl; diff --git a/src/core/utils/theme.jsx b/src/core/utils/theme.jsx index 0a36eee..672e8a8 100644 --- a/src/core/utils/theme.jsx +++ b/src/core/utils/theme.jsx @@ -1,18 +1,29 @@ +import {colord} from "colord"; + const theme = { - palette: { - primary: { - main: "#084070", - contrastText: "#fff", - light: "#2c6291", - dark: "#11293e", + palette: { + primary: { + main: process.env.NEXT_PUBLIC_PRIMARY_MAIN, + contrastText: "#FFFFFF", + light: colord(process.env.NEXT_PUBLIC_PRIMARY_MAIN).lighten(0.1).toHex(), + dark: colord(process.env.NEXT_PUBLIC_PRIMARY_MAIN).darken(0.1).toHex(), + }, + secondary: { + main: process.env.NEXT_PUBLIC_SECONDARY_MAIN, + contrastText: "#FFFFFF", + light: colord(process.env.NEXT_PUBLIC_SECONDARY_MAIN).lighten(0.1).toHex(), + dark: colord(process.env.NEXT_PUBLIC_SECONDARY_MAIN).darken(0.1).toHex(), + }, }, - secondary: { - main: "#FF4E00", - contrastText: "#fff", - light: "#ed743e", - dark: "#ad3a07", + components: { + MuiBackdrop: { + styleOverrides: { + root: { + backgroundColor: colord(process.env.NEXT_PUBLIC_PRIMARY_MAIN).darken(0.2).alpha(0.7).toHex(), + }, + }, + }, }, - }, }; export default theme; diff --git a/src/layouts/AppLayout.jsx b/src/layouts/AppLayout.jsx index 2f7988e..611e707 100644 --- a/src/layouts/AppLayout.jsx +++ b/src/layouts/AppLayout.jsx @@ -1,85 +1,105 @@ import theme from "@/core/utils/theme"; +import useLanguage from "@/lib/app/hooks/useLanguage"; import useLoading from "@/lib/app/hooks/useLoading"; import useUser from "@/lib/app/hooks/useUser"; import Head from "next/head"; import NextNProgress from "nextjs-progressbar"; -import { useEffect } from "react"; +import {useEffect} from "react"; +import {ToastContainer} from "react-toastify"; +import useDirection from "@/lib/app/hooks/useDirection"; +import "react-toastify/dist/ReactToastify.css"; -function AppLayout({ children, isBot }) { - const { setLoadingPage } = useLoading(); - const { token, isAuth } = useUser(); - useEffect(() => { - if (token) { - if (isAuth) { - setLoadingPage(false); - return; +function AppLayout({children, isBot}) { + const {languageIsReady} = useLanguage(); + const {setLoadingPage} = useLoading(); + const {userChangedLanguage, token, isAuth} = useUser(); + const {directionApp} = useDirection(); + + useEffect(() => { + if (languageIsReady) { + if (token) { + if (isAuth) { + if (userChangedLanguage) { + setLoadingPage(true); + return; + } + setLoadingPage(false); + return; + } + setLoadingPage(true); + return; + } + setLoadingPage(false); + return; } setLoadingPage(true); - return; - } - setLoadingPage(false); - return; - }, [token, isAuth]); + }, [languageIsReady, token, isAuth, userChangedLanguage]); - return ( - <> - - - - - - - - - - - - - - - - - - - - - - {children} - - ); + if (!isBot) { + if (userChangedLanguage) return; + if (!languageIsReady) return; + } + + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + {children} + + ); } export default AppLayout; diff --git a/src/layouts/CenterLayout.jsx b/src/layouts/CenterLayout.jsx index 4c8767f..1e1b8bf 100644 --- a/src/layouts/CenterLayout.jsx +++ b/src/layouts/CenterLayout.jsx @@ -1,18 +1,18 @@ -import { Fade, Stack } from "@mui/material"; +import {Fade, Stack} from "@mui/material"; const CenterLayout = (props) => { - return ( - - - {props.children} - - - ); + return ( + + + {props.children} + + + ); }; export default CenterLayout; diff --git a/src/layouts/FullPageLayout.jsx b/src/layouts/FullPageLayout.jsx index cbf2102..d6ed61e 100644 --- a/src/layouts/FullPageLayout.jsx +++ b/src/layouts/FullPageLayout.jsx @@ -1,21 +1,21 @@ -import { Stack } from "@mui/material"; +import {Stack} from "@mui/material"; const FullPageLayout = (props) => { - return ( - - {props.children} - - ); + return ( + + {props.children} + + ); }; export default FullPageLayout; diff --git a/src/layouts/MuiLayout.jsx b/src/layouts/MuiLayout.jsx index ba891d0..1c9e9b9 100644 --- a/src/layouts/MuiLayout.jsx +++ b/src/layouts/MuiLayout.jsx @@ -1,76 +1,75 @@ -import NoSsrHandler from "@/core/components/isBotHandler"; -import { - createEmotionCacheRtl -} from "@/core/utils/createEmotionCache"; +import NoSsrHandler from "@/core/components/NoSsrHandler"; +import {createEmotionCacheRtl} from "@/core/utils/createEmotionCache"; import themeRtl from "@/core/utils/theme-rtl"; -import { CacheProvider } from "@emotion/react"; -import { GlobalStyles } from "@mui/material"; +import {CacheProvider} from "@emotion/react"; +import {GlobalStyles} from "@mui/material"; import CssBaseline from "@mui/material/CssBaseline"; -import { ThemeProvider } from "@mui/material/styles"; +import {ThemeProvider} from "@mui/material/styles"; import Head from "next/head"; const clientSideEmotionCacheRtl = createEmotionCacheRtl(); -const MuiLayout = ({ children, isBot }) => { +const MuiLayout = ({children, isBot}) => { - const emotionCache = clientSideEmotionCacheRtl; + const emotionCache = clientSideEmotionCacheRtl; - const theme = themeRtl; - return ( - - - - - - - + + + + + + + "*::-moz-scrollbar-thumb": { + backgroundColor: `${theme.palette.primary.light}80`, + }, + [`@media (max-width: ${theme.breakpoints.values.sm}px)`]: { + "*::-webkit-scrollbar": { + height: "4px", + }, + }, - - {children} - - - - ); + body: { + width: "100vw", + height: "100vh", + }, + "#__next": { + width: "100%", + height: "100%", + }, + }} + /> + + + {children} + + + + ); }; export default MuiLayout; diff --git a/src/layouts/ScrollableLayout.jsx b/src/layouts/ScrollableLayout.jsx index 5ab58ca..583edd7 100644 --- a/src/layouts/ScrollableLayout.jsx +++ b/src/layouts/ScrollableLayout.jsx @@ -1,25 +1,25 @@ -import { Box, Fade } from "@mui/material"; +import {Box, Fade} from "@mui/material"; const ScrollableLayout = (props) => { - const overflowY = props?.y || "hidden"; - const overflowX = props?.x || "hidden"; + const overflowY = props?.y || "hidden"; + const overflowX = props?.x || "hidden"; - return ( - - - {props.children} - - - ); + return ( + + + {props.children} + + + ); }; export default ScrollableLayout; diff --git a/src/layouts/dashboardLayouts/breadcrumbs/BreadcrumbItem.jsx b/src/layouts/dashboardLayouts/breadcrumbs/BreadcrumbItem.jsx index ccff4c9..c233be3 100644 --- a/src/layouts/dashboardLayouts/breadcrumbs/BreadcrumbItem.jsx +++ b/src/layouts/dashboardLayouts/breadcrumbs/BreadcrumbItem.jsx @@ -1,19 +1,19 @@ import LinkRouting from "@/core/components/LinkRouting"; -import { Typography } from "@mui/material"; -import { useTranslations } from "next-intl"; +import {Typography} from "@mui/material"; +import {useTranslations} from "next-intl"; export default function BreadcrumbItem(props) { - const t = useTranslations(); - const isLast = props.index === props.RouterArray.length - 1; - const url = `/${props.RouterArray.slice(0, props.index + 1).join("/")}`; + const t = useTranslations(); + const isLast = props.index === props.RouterArray.length - 1; + const url = `/${props.RouterArray.slice(0, props.index + 1).join("/")}`; - return isLast ? ( - - {t("sidebar." + props.label)} - - ) : ( - - {t("sidebar." + props.label)} - - ); + return isLast ? ( + + {t("sidebar." + props.label)} + + ) : ( + + {t("sidebar." + props.label)} + + ); } diff --git a/src/layouts/dashboardLayouts/breadcrumbs/index.jsx b/src/layouts/dashboardLayouts/breadcrumbs/index.jsx index 3123a12..310323e 100644 --- a/src/layouts/dashboardLayouts/breadcrumbs/index.jsx +++ b/src/layouts/dashboardLayouts/breadcrumbs/index.jsx @@ -1,49 +1,62 @@ -import { useRouter } from "next/router"; -import { Box, Breadcrumbs } from "@mui/material"; -import { useTheme } from "@mui/material/styles"; -import { NavigateBefore, NavigateNext } from "@mui/icons-material"; +import {useRouter} from "next/router"; +import {Box, Breadcrumbs} from "@mui/material"; +import {useTheme} from "@mui/material/styles"; +import {NavigateBefore, NavigateNext} from "@mui/icons-material"; import BreadcrumbItem from "./BreadcrumbItem"; +import useUser from "@/lib/app/hooks/useUser"; const BreadCrumbs = (props) => { - const { isVisible } = props; - const theme = useTheme(); - const router = useRouter(); + const {isVisible} = props; + const theme = useTheme(); + const router = useRouter(); + const {user} = useUser(); - if (!isVisible) { - return null; - } + if (!isVisible) { + return null; + } - const { pathname } = router; - const RouterArray = pathname.split("/").filter((segment) => segment !== ""); + const {pathname} = router; + const RouterArray = pathname.split("/").filter((segment) => segment !== ""); - if (RouterArray.length === 1) { - return null; - } + // every part of your router you want to remove add it to this array + const segmentsToRemove = ["navgan", "refahi", "[id]"]; - return ( - - - ) : ( - - ) + segmentsToRemove.forEach((segmentToRemove) => { + const index = RouterArray.indexOf(segmentToRemove); + if (index !== -1) { + RouterArray.splice(index, 1); } - aria-label="breadcrumb" - > - {RouterArray.map((segment, index) => ( - - ))} - - - ); + }); + + + if (RouterArray.length === 1) { + return null; + } + + return ( + + + ) : ( + + ) + } + aria-label="breadcrumb" + > + {RouterArray.map((segment, index) => ( + + ))} + + + ); }; export default BreadCrumbs; diff --git a/src/layouts/dashboardLayouts/header/ProfileData.jsx b/src/layouts/dashboardLayouts/header/ProfileData.jsx index c3fdf58..13ceda1 100644 --- a/src/layouts/dashboardLayouts/header/ProfileData.jsx +++ b/src/layouts/dashboardLayouts/header/ProfileData.jsx @@ -1,18 +1,15 @@ -import { Avatar, Stack, Typography } from "@mui/material"; +import {Avatar, Stack} from "@mui/material"; import useUser from "@/lib/app/hooks/useUser"; export default function ProfileData() { - const { user } = useUser(); - return ( - - - - {user.user_username} - - - ); + const {user} = useUser(); + return ( + + + + ); } diff --git a/src/layouts/dashboardLayouts/header/ProfileMenu.jsx b/src/layouts/dashboardLayouts/header/ProfileMenu.jsx index 50f34db..e628e52 100644 --- a/src/layouts/dashboardLayouts/header/ProfileMenu.jsx +++ b/src/layouts/dashboardLayouts/header/ProfileMenu.jsx @@ -1,61 +1,62 @@ -import { Avatar, Menu, IconButton, Tooltip } from "@mui/material"; -import { useState } from "react"; +import {Avatar, IconButton, Menu, Tooltip} from "@mui/material"; +import {useState} from "react"; import ProfileData from "./ProfileData"; import ProfileOptions from "./ProfileOptions"; -import { useTranslations } from "next-intl"; +import {useTranslations} from "next-intl"; import useUser from "@/lib/app/hooks/useUser"; function ProfileMenu() { - const t = useTranslations(); - const [anchorElUser, setAnchorElUser] = useState(null); - const { user } = useUser(); + const t = useTranslations(); + const [anchorElUser, setAnchorElUser] = useState(null); + const {user} = useUser(); - const handleOpenUserMenu = (event) => { - setAnchorElUser(event.currentTarget); - }; - const handleCloseUserMenu = () => { - setAnchorElUser(null); - }; + const handleOpenUserMenu = (event) => { + setAnchorElUser(event.currentTarget); + }; + const handleCloseUserMenu = () => { + setAnchorElUser(null); + }; - return ( - <> - - - - - - - - - - - ); + return ( + <> + + + + + + + + + + + ); } + export default ProfileMenu; diff --git a/src/layouts/dashboardLayouts/header/ProfileOptionLogOut.jsx b/src/layouts/dashboardLayouts/header/ProfileOptionLogOut.jsx index f56db6c..2a6cf85 100644 --- a/src/layouts/dashboardLayouts/header/ProfileOptionLogOut.jsx +++ b/src/layouts/dashboardLayouts/header/ProfileOptionLogOut.jsx @@ -1,49 +1,49 @@ -import { Box, Button, MenuItem, Typography } from "@mui/material"; +import {Box, Button, MenuItem, Typography} from "@mui/material"; import MeetingRoomIcon from "@mui/icons-material/MeetingRoom"; import useUser from "@/lib/app/hooks/useUser"; -import { useTranslations } from "next-intl"; +import {useTranslations} from "next-intl"; -export default function ProfileOptionLogOut({ handleCloseUserMenu }) { - const t = useTranslations(); - const { clearToken } = useUser(); - const handleClickLogOut = () => { - handleCloseUserMenu(); - clearToken(); - }; - return ( - <> - - - - - - - {t("header.logout")} - - - - - ); +export default function ProfileOptionLogOut({handleCloseUserMenu}) { + const t = useTranslations(); + const {clearToken} = useUser(); + const handleClickLogOut = () => { + handleCloseUserMenu(); + clearToken(); + }; + return ( + <> + + + + + + + {t("header.logout")} + + + + + ); } diff --git a/src/layouts/dashboardLayouts/header/ProfileOptions.jsx b/src/layouts/dashboardLayouts/header/ProfileOptions.jsx index bf63212..6e7bdba 100644 --- a/src/layouts/dashboardLayouts/header/ProfileOptions.jsx +++ b/src/layouts/dashboardLayouts/header/ProfileOptions.jsx @@ -1,49 +1,49 @@ -import { Box, MenuItem, Typography } from "@mui/material"; -import { NextLinkComposed } from "@/core/components/LinkRouting"; -import { useTranslations } from "next-intl"; +import {Box, MenuItem, Typography} from "@mui/material"; +import {NextLinkComposed} from "@/core/components/LinkRouting"; +import {useTranslations} from "next-intl"; import headerProfileItems from "@/core/data/headerProfileItems"; import ProfileOptionLogOut from "./ProfileOptionLogOut"; -export default function ProfileOptions({ handleCloseUserMenu }) { - const t = useTranslations(); +export default function ProfileOptions({handleCloseUserMenu}) { + const t = useTranslations(); - return ( - <> - {headerProfileItems.map((profile_item) => ( - - - - {profile_item.icon} - - - {t(profile_item.name)} - - - - ))} - - - ); + return ( + <> + {headerProfileItems.map((profile_item) => ( + + + + {profile_item.icon} + + + {t(profile_item.name)} + + + + ))} + + + ); } diff --git a/src/layouts/dashboardLayouts/header/index.jsx b/src/layouts/dashboardLayouts/header/index.jsx index cd1e4a0..8760960 100644 --- a/src/layouts/dashboardLayouts/header/index.jsx +++ b/src/layouts/dashboardLayouts/header/index.jsx @@ -1,80 +1,72 @@ import MenuIcon from "@mui/icons-material/Menu"; -import { - AppBar, - Box, - Container, - CssBaseline, - IconButton, - Stack, - Toolbar, - useTheme -} from "@mui/material"; +import {AppBar, Box, Container, CssBaseline, IconButton, Stack, Toolbar, useTheme} from "@mui/material"; import ProfileMenu from "./ProfileMenu"; -function Header({ drawerWidth, handleDrawerToggle }) { - const theme = useTheme(); +function Header({drawerWidth, handleDrawerToggle}) { + const theme = useTheme(); - return ( - <> - - - - - - - - - - - + + - - - - - - - - - - ); + > + + + + + + + + + + + + + + + + + + + ); } + export default Header; diff --git a/src/layouts/dashboardLayouts/index.jsx b/src/layouts/dashboardLayouts/index.jsx index f1478bf..c32c09b 100644 --- a/src/layouts/dashboardLayouts/index.jsx +++ b/src/layouts/dashboardLayouts/index.jsx @@ -1,50 +1,49 @@ -import { useState } from "react"; +import {useState} from "react"; import FullPageLayout from "../FullPageLayout"; import Header from "./header"; import Sidebar from "./sidebar"; -import { Toolbar } from "@mui/material"; +import {Toolbar} from "@mui/material"; import BreadCrumbs from "./breadcrumbs"; -import { ToastContainer } from "react-toastify"; +import {ToastContainer} from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; import useDirection from "@/lib/app/hooks/useDirection"; const drawerWidth = 240; const DashboardLayouts = (props) => { - const { directionApp } = useDirection(); - const { window } = props; - const [mobileOpen, setMobileOpen] = useState(false); - const container = - window !== undefined ? () => window().document.body : undefined; + const {directionApp} = useDirection(); + const {window} = props; + const [mobileOpen, setMobileOpen] = useState(false); + const container = + window !== undefined ? () => window().document.body : undefined; - const handleDrawerToggle = () => { - setMobileOpen(!mobileOpen); - }; - return ( - -
- - - - - - {props.children} + const handleDrawerToggle = () => { + setMobileOpen(!mobileOpen); + }; + return ( + +
+ + + + + + {props.children} + + - - {directionApp === "rtl" ? : } - - ); + ); }; export default DashboardLayouts; diff --git a/src/layouts/dashboardLayouts/sidebar/SidebarDrawer.jsx b/src/layouts/dashboardLayouts/sidebar/SidebarDrawer.jsx index 4c65885..5eff37a 100644 --- a/src/layouts/dashboardLayouts/sidebar/SidebarDrawer.jsx +++ b/src/layouts/dashboardLayouts/sidebar/SidebarDrawer.jsx @@ -1,29 +1,26 @@ -import { Divider, Stack, Toolbar, Typography } from "@mui/material"; -import { useTranslations } from "next-intl"; +import useUser from "@/lib/app/hooks/useUser"; +import {Divider, Stack, Toolbar, Typography} from "@mui/material"; +import {useTranslations} from "next-intl"; import SidebarList from "./SidebarList"; -import StyledImage from "@/core/components/StyledImage"; -const SidebarDrawer = ({ handleDrawerToggle }) => { - const t = useTranslations(); - return ( - <> - - - - {t("app_short_name")} - - - { - t("user_navy") /* make if on thease t("user_welfare_services") - t("user_navy") */ - } - - - - - - - ); +const SidebarDrawer = ({handleDrawerToggle}) => { + const {user} = useUser(); + const t = useTranslations(); + + return ( + <> + + + + {t("app_short_name")} + + {user.type_name} + + + + + + ); }; export default SidebarDrawer; diff --git a/src/layouts/dashboardLayouts/sidebar/SidebarList.jsx b/src/layouts/dashboardLayouts/sidebar/SidebarList.jsx index 79dd93e..6cd6847 100644 --- a/src/layouts/dashboardLayouts/sidebar/SidebarList.jsx +++ b/src/layouts/dashboardLayouts/sidebar/SidebarList.jsx @@ -1,56 +1,69 @@ -import { Divider, List } from "@mui/material"; -import { Fragment, useEffect, useReducer } from "react"; +import {Divider, List} from "@mui/material"; +import {Fragment, useEffect, useReducer} from "react"; import SidebarListItem from "./SidebarListItem"; import sidebarMenu from "@/core/data/sidebarMenu"; -import { useRouter } from "next/router"; +import {useRouter} from "next/router"; +import useUser from "@/lib/app/hooks/useUser"; function reducer(state, action) { - switch (action.type) { - case "COLLAPSE_MENU": - return state.map((itemsArr) => - itemsArr.map((item) => - action.key == item.key - ? { ...item, showSubItem: !item.showSubItem } - : item - ) - ); - case "SELECTED": - return state.map((itemsArr) => - itemsArr.map((item) => - action.route == item.route - ? { ...item, selected: true } - : { ...item, selected: false } - ) - ); - default: - throw new Error(); - } + switch (action.type) { + case "COLLAPSE_MENU": + return state.map((itemsArr) => + itemsArr.map((item) => + action.key == item.key + ? {...item, showSubItem: !item.showSubItem} + : item + ) + ); + case "SELECTED": + return state.map((itemsArr) => + itemsArr.map((item) => + action.route == item.route + ? {...item, selected: true} + : {...item, selected: false} + ) + ); + default: + throw new Error(); + } } -export default function SidebarList({ handleDrawerToggle }) { - const [itemMenu, dispatch] = useReducer(reducer, sidebarMenu); +export default function SidebarList({handleDrawerToggle}) { + const [itemMenu, dispatch] = useReducer(reducer, sidebarMenu); + const {user} = useUser(); - // activate current page in menu - const router = useRouter(); - useEffect(() => { - dispatch({ type: "SELECTED", route: router.pathname }); - }, [router.pathname]); + // activate current page in menu + const router = useRouter(); + useEffect(() => { + dispatch({type: "SELECTED", route: router.pathname}); + }, [router.pathname]); - return ( - - {itemMenu.map((itemArr, index) => ( - - {itemArr.map((item) => ( - - ))} - - - ))} - - ); + return ( + + {itemMenu.map((itemArr, index) => ( + + {itemArr.map((item) => { + if ( + (item.userType === user.type_id || item.userType === 0) && + (user[item.permission_name] || item.permission_name === "all") + ) { + return ( + + ); + } else { + return null; + } + })} + + + ) + )} + + ) + ; } diff --git a/src/layouts/dashboardLayouts/sidebar/SidebarListItem.jsx b/src/layouts/dashboardLayouts/sidebar/SidebarListItem.jsx index ba270a5..f663413 100644 --- a/src/layouts/dashboardLayouts/sidebar/SidebarListItem.jsx +++ b/src/layouts/dashboardLayouts/sidebar/SidebarListItem.jsx @@ -1,64 +1,59 @@ -import { NextLinkComposed } from "@/core/components/LinkRouting"; +import {NextLinkComposed} from "@/core/components/LinkRouting"; import ExpandLess from "@mui/icons-material/ExpandLess"; import ExpandMore from "@mui/icons-material/ExpandMore"; -import { - ListItem, - ListItemButton, - ListItemIcon, - ListItemText, -} from "@mui/material"; -import { useTranslations } from "next-intl"; -import { Fragment } from "react"; +import {ListItem, ListItemButton, ListItemIcon, ListItemText,} from "@mui/material"; +import {useTranslations} from "next-intl"; +import {Fragment} from "react"; import SidebarListSubItem from "./SidebarListSubItem"; -const SidebarListItem = ({ item, dispatch, handleDrawerToggle }) => { - const t = useTranslations(); +const SidebarListItem = ({item, dispatch, handleDrawerToggle}) => { + const t = useTranslations(); - return ( - - - { - if (item.type == "menu") { - dispatch({ type: "COLLAPSE_MENU", key: item.key }); - } - handleDrawerToggle(); - }} - sx={{ - minHeight: 48, - }} - > - - {item.icon} - - + return ( + + + { + if (item.type == "menu") { + dispatch({type: "COLLAPSE_MENU", key: item.key}); + } + handleDrawerToggle(); + }} + sx={{ + minHeight: 48, + }} + > + + {item.icon} + + - {item.type == "menu" && - (item.showSubItem ? : )} - - - {item.subItem && ( - - )} - - ); + {item.type == "menu" && + (item.showSubItem ? : )} + + + {item.subItem && ( + + )} + + ); }; export default SidebarListItem; diff --git a/src/layouts/dashboardLayouts/sidebar/SidebarListSubItem.jsx b/src/layouts/dashboardLayouts/sidebar/SidebarListSubItem.jsx index f960efb..3407081 100644 --- a/src/layouts/dashboardLayouts/sidebar/SidebarListSubItem.jsx +++ b/src/layouts/dashboardLayouts/sidebar/SidebarListSubItem.jsx @@ -1,54 +1,48 @@ -import { NextLinkComposed } from "@/core/components/LinkRouting"; +import {NextLinkComposed} from "@/core/components/LinkRouting"; import InboxIcon from "@mui/icons-material/MoveToInbox"; -import { - Collapse, - List, - ListItemButton, - ListItemIcon, - ListItemText, -} from "@mui/material"; -import { useTranslations } from "next-intl"; -import { Fragment } from "react"; +import {Collapse, List, ListItemButton, ListItemIcon, ListItemText,} from "@mui/material"; +import {useTranslations} from "next-intl"; +import {Fragment} from "react"; -const SidebarListSubItem = ({ item, handleDrawerToggle }) => { - const t = useTranslations(); +const SidebarListSubItem = ({item, handleDrawerToggle}) => { + const t = useTranslations(); - return ( - - - {item.subItem.map((subitem, index) => ( - - { - if (item.type == "menu") { - dispatch({ type: "COLLAPSE_MENU", key: item.key }); - } - handleDrawerToggle(); - }} - > - - - - - - - ))} - - - ); + return ( + + + {item.subItem.map((subitem, index) => ( + + { + if (item.type == "menu") { + dispatch({type: "COLLAPSE_MENU", key: item.key}); + } + handleDrawerToggle(); + }} + > + + + + + + + ))} + + + ); }; export default SidebarListSubItem; diff --git a/src/layouts/dashboardLayouts/sidebar/index.jsx b/src/layouts/dashboardLayouts/sidebar/index.jsx index dcf7fe2..2498dfd 100644 --- a/src/layouts/dashboardLayouts/sidebar/index.jsx +++ b/src/layouts/dashboardLayouts/sidebar/index.jsx @@ -1,46 +1,46 @@ -import { Box, Drawer } from "@mui/material"; +import {Box, Drawer} from "@mui/material"; import SidebarDrawer from "./SidebarDrawer"; const Sidebar = (props) => { - return ( - - - - - - - - - ); + return ( + + + + + + + + + ); }; export default Sidebar; diff --git a/src/lib/app/contexts/language.jsx b/src/lib/app/contexts/language.jsx index c8ac313..e3f41f4 100644 --- a/src/lib/app/contexts/language.jsx +++ b/src/lib/app/contexts/language.jsx @@ -1,99 +1,99 @@ -import { FA_DATATABLE_LOCALIZATION } from "&/locales/fa/datatable"; -import { useRouter } from "next/router"; -import { createContext, useEffect, useState } from "react"; +import {FA_DATATABLE_LOCALIZATION} from "&/locales/fa/datatable"; +import {useRouter} from "next/router"; +import {createContext, useEffect, useState} from "react"; import useUser from "../hooks/useUser"; export const LanguageContext = createContext(); -export const LanguageProvider = ({ children }) => { - const router = useRouter(); - const languageList = [ - { - key: "fa", - dir: "rtl", - name: "فارسی", - fontFamily: `IRANSans, sans-serif`, - tableLocalization: FA_DATATABLE_LOCALIZATION, - } - ]; - const { user, userChangedLanguage, changeLanguageState } = useUser(); - const [languageIsReady, setLanguageIsReady] = useState(false); - const [languageApp, setLanguageApp] = useState(); - const [directionApp, setDirectionApp] = useState( - process.env.NEXT_PUBLIC_DEFAULT_DIRECTION - ); - - useEffect(() => { - const lang = localStorage.getItem("_language"); - - if (!lang && !languageApp) { - setLanguageApp(process.env.NEXT_PUBLIC_DEFAULT_LANGUAGE); - } else if (lang) { - setLanguageApp(lang); - } - }, []); - - useEffect(() => { - if (!languageApp) return; - - const lang = localStorage.getItem("_language"); - - if (!lang) { - localStorage.setItem("_language", languageApp); - } else { - if (languageApp != lang) { - localStorage.setItem("_language", languageApp); - } - } - }, [languageApp]); - - useEffect(() => { - if (!router.isReady) return; - if (user.user_language) { - if (user.user_language != languageApp) { - setLanguageApp(user.user_language); - return; - } - } - - if (languageApp != router.locale) { - router.replace( - { pathname: router.pathname, query: router.query }, - router.asPath, +export const LanguageProvider = ({children}) => { + const router = useRouter(); + const languageList = [ { - locale: languageApp, + key: "fa", + dir: "rtl", + name: "فارسی", + fontFamily: `IRANSans, sans-serif`, + tableLocalization: FA_DATATABLE_LOCALIZATION, } - ); - return; - } - for (const lang of languageList) { - if (languageApp != lang.key) continue; - setDirectionApp(lang.dir); - document.dir = lang.dir; - } + ]; + const {user, userChangedLanguage, changeLanguageState} = useUser(); + const [languageIsReady, setLanguageIsReady] = useState(false); + const [languageApp, setLanguageApp] = useState(); + const [directionApp, setDirectionApp] = useState( + process.env.NEXT_PUBLIC_DEFAULT_DIRECTION + ); - const timer = setTimeout(() => { - changeLanguageState(false); - setLanguageIsReady(true); - }, 1000); + useEffect(() => { + const lang = localStorage.getItem("_language"); - return () => { - clearTimeout(timer); - }; - }, [router.locale, router.isReady, userChangedLanguage, languageApp]); + if (!lang && !languageApp) { + setLanguageApp(process.env.NEXT_PUBLIC_DEFAULT_LANGUAGE); + } else if (lang) { + setLanguageApp(lang); + } + }, []); - return ( - - {children} - - ); + useEffect(() => { + if (!languageApp) return; + + const lang = localStorage.getItem("_language"); + + if (!lang) { + localStorage.setItem("_language", languageApp); + } else { + if (languageApp != lang) { + localStorage.setItem("_language", languageApp); + } + } + }, [languageApp]); + + useEffect(() => { + if (!router.isReady) return; + if (user.user_language) { + if (user.user_language != languageApp) { + setLanguageApp(user.user_language); + return; + } + } + + if (languageApp != router.locale) { + router.replace( + {pathname: router.pathname, query: router.query}, + router.asPath, + { + locale: languageApp, + } + ); + return; + } + for (const lang of languageList) { + if (languageApp != lang.key) continue; + setDirectionApp(lang.dir); + document.dir = lang.dir; + } + + const timer = setTimeout(() => { + changeLanguageState(false); + setLanguageIsReady(true); + }, 1000); + + return () => { + clearTimeout(timer); + }; + }, [router.locale, router.isReady, userChangedLanguage, languageApp]); + + return ( + + {children} + + ); }; diff --git a/src/lib/app/contexts/loading.jsx b/src/lib/app/contexts/loading.jsx index 6e95a8c..f5b8a47 100644 --- a/src/lib/app/contexts/loading.jsx +++ b/src/lib/app/contexts/loading.jsx @@ -1,14 +1,14 @@ import LoadingHardPage from "@/core/components/LoadingHardPage"; -import { createContext, useState } from "react"; +import {createContext, useState} from "react"; export const LoadingContext = createContext(); -export const LoadingProvider = ({ children }) => { - const [loadingPage, setLoadingPage] = useState(false); - return ( - - - {children} - - ); +export const LoadingProvider = ({children}) => { + const [loadingPage, setLoadingPage] = useState(false); + return ( + + + {children} + + ); }; diff --git a/src/lib/app/contexts/user.jsx b/src/lib/app/contexts/user.jsx index 49d55af..827a8af 100644 --- a/src/lib/app/contexts/user.jsx +++ b/src/lib/app/contexts/user.jsx @@ -1,144 +1,133 @@ -import { - GET_USER_ROUTE, - SET_LANGUAGE -} from "@/core/data/apiRoutes"; +import {USER_INFO} from "@/core/data/apiRoutes"; import axios from "axios"; -import { createContext, useCallback, useEffect, useReducer } from "react"; +import {createContext, useCallback, useEffect, useReducer} from "react"; +import {errorRequest, errorResponse, errorSetting} from "@/core/utils/errorHandler"; const initialUser = { - isAuth: false, - userChangedLanguage: false, - token: null, - user: {}, + isAuth: false, + userChangedLanguage: false, + token: null, + user: {}, }; const reducer = (state, action) => { - switch (action.type) { - case "CLEAR_USER": - return { ...state, user: {} }; - case "CHANGE_USER": - return { ...state, user: action.user }; - case "CHANGE_USER_LANGUAGE": - return { - ...state, - user: { ...state.user, user_language: action.language }, - }; - case "CHANGE_AUTH_STATE": - return { ...state, isAuth: action.isAuth }; - case "CHANGE_LANGUAGE_STATE": - return { ...state, userChangedLanguage: action.userChangedLanguage }; - case "CLEAR_TOKEN": - localStorage.removeItem("_token"); - return { ...state, token: null }; - case "SET_TOKEN": - localStorage.setItem("_token", action.token); - return { ...state, token: action.token }; - default: - return state; - } + switch (action.type) { + case "CLEAR_USER": + return {...state, user: {}}; + case "CHANGE_USER": + return {...state, user: action.user}; + case "CHANGE_USER_LANGUAGE": + return { + ...state, + user: {...state.user, user_language: action.language}, + }; + case "CHANGE_AUTH_STATE": + return {...state, isAuth: action.isAuth}; + case "CHANGE_LANGUAGE_STATE": + return {...state, userChangedLanguage: action.userChangedLanguage}; + case "CLEAR_TOKEN": + localStorage.removeItem("_token"); + return {...state, token: null}; + case "SET_TOKEN": + localStorage.setItem("_token", action.token); + return {...state, token: action.token}; + default: + return state; + } }; export const UserContext = createContext(); -export const UserProvider = ({ children }) => { - const [state, dispatch] = useReducer(reducer, initialUser); +export const UserProvider = ({children}) => { + const [state, dispatch] = useReducer(reducer, initialUser); - const clearUser = useCallback(() => { - dispatch({ type: "CLEAR_USER" }); - }, []); + const clearUser = useCallback(() => { + dispatch({type: "CLEAR_USER"}); + }, []); - const changeUser = useCallback((user) => { - dispatch({ type: "CHANGE_USER", user }); - }, []); + const changeUser = useCallback((user) => { + dispatch({type: "CHANGE_USER", user}); + }, []); - const changeUserLanguage = useCallback( - (language) => { - dispatch({ type: "CHANGE_USER_LANGUAGE", language }); - axios - .post( - SET_LANGUAGE, - { language: language }, - { - headers: { - authorization: `Bearer ${state.token}`, - }, - } - ) - .then(() => { - getUser((data) => { + const changeUserLanguage = useCallback(/* for multi language app */); + + const changeAuthState = useCallback((isAuth) => { + dispatch({type: "CHANGE_AUTH_STATE", isAuth}); + }, []); + + const changeLanguageState = useCallback((userChangedLanguage) => { + dispatch({type: "CHANGE_LANGUAGE_STATE", userChangedLanguage}); + }, []); + + const clearToken = useCallback(() => { + dispatch({type: "CLEAR_TOKEN"}); + }, []); + + const setToken = useCallback((token) => { + dispatch({type: "SET_TOKEN", token}); + }, []); + + const getUser = useCallback( + (callback = () => { + }) => { + axios + .get(USER_INFO, { + headers: {authorization: `Bearer ${state.token}`}, + }) + .then(({data}) => { + if (typeof callback === "function") callback(data); + }) + .catch(error => { + if (error.response) { + errorResponse(error.response, clearToken, null, false) + } else if (error.request) { + errorRequest(null, false) + } else { + errorSetting(null, false) + } + }) + + }, + [state.token] + ); + + useEffect(() => { + const localToken = localStorage.getItem("_token"); + if (localToken) dispatch({type: "SET_TOKEN", token: localToken}); + }, []); + + useEffect(() => { + if (!state.token) { + clearUser(); + changeAuthState(false); + changeLanguageState(false); + return; + } + getUser((data) => { changeUser(data); - }); + changeAuthState(true); + changeLanguageState(true); }); - }, - [state.token] - ); + }, [state.token]); - const changeAuthState = useCallback((isAuth) => { - dispatch({ type: "CHANGE_AUTH_STATE", isAuth }); - }, []); - - const changeLanguageState = useCallback((userChangedLanguage) => { - dispatch({ type: "CHANGE_LANGUAGE_STATE", userChangedLanguage }); - }, []); - - const clearToken = useCallback(() => { - dispatch({ type: "CLEAR_TOKEN" }); - }, []); - - const setToken = useCallback((token) => { - dispatch({ type: "SET_TOKEN", token }); - }, []); - - const getUser = useCallback( - (callback = () => {}) => { - axios - .get(GET_USER_ROUTE, { - headers: { authorization: `Bearer ${state.token}` }, - }) - .then(({ data }) => { - if (typeof callback === "function") callback(data); - }); - }, - [state.token] - ); - - useEffect(() => { - const localToken = localStorage.getItem("_token"); - if (localToken) dispatch({ type: "SET_TOKEN", token: localToken }); - }, []); - - useEffect(() => { - if (!state.token) { - clearUser(); - changeAuthState(false); - changeLanguageState(false); - return; - } - getUser((data) => { - changeUser(data); - changeAuthState(true); - changeLanguageState(true); - }); - }, [state.token]); - - return ( - - {children} - - ); + return ( + + {children} + + ); }; diff --git a/src/lib/app/hooks/useDirection.jsx b/src/lib/app/hooks/useDirection.jsx index e45cb24..b2e01fe 100644 --- a/src/lib/app/hooks/useDirection.jsx +++ b/src/lib/app/hooks/useDirection.jsx @@ -1,10 +1,10 @@ -import { useContext } from "react"; -import { LanguageContext } from "../contexts/language"; +import {useContext} from "react"; +import {LanguageContext} from "../contexts/language"; const useDirection = () => { - const { directionApp } = useContext(LanguageContext); + const {directionApp} = useContext(LanguageContext); - return { directionApp }; + return {directionApp}; }; export default useDirection; diff --git a/src/lib/app/hooks/useLanguage.jsx b/src/lib/app/hooks/useLanguage.jsx index 66e2ee0..d663835 100644 --- a/src/lib/app/hooks/useLanguage.jsx +++ b/src/lib/app/hooks/useLanguage.jsx @@ -1,28 +1,28 @@ -import { useContext } from "react"; -import { LanguageContext } from "../contexts/language"; +import {useContext} from "react"; +import {LanguageContext} from "../contexts/language"; import useUser from "./useUser"; const useLanguage = () => { - const { isAuth, changeUserLanguage } = useUser(); - const { - languageApp, - setLanguageApp, - languageIsReady, - setLanguageIsReady, - languageList, - } = useContext(LanguageContext); + const {isAuth, changeUserLanguage} = useUser(); + const { + languageApp, + setLanguageApp, + languageIsReady, + setLanguageIsReady, + languageList, + } = useContext(LanguageContext); - const changeLanguage = (lang) => { - if (lang == languageApp) return; + const changeLanguage = (lang) => { + if (lang == languageApp) return; - setLanguageIsReady(false); - setLanguageApp(lang); - if (isAuth) { - changeUserLanguage(lang); - } - }; + setLanguageIsReady(false); + setLanguageApp(lang); + if (isAuth) { + changeUserLanguage(lang); + } + }; - return { languageApp, changeLanguage, languageIsReady, languageList }; + return {languageApp, changeLanguage, languageIsReady, languageList}; }; export default useLanguage; diff --git a/src/lib/app/hooks/useLoading.jsx b/src/lib/app/hooks/useLoading.jsx index d74a87e..a691bd7 100644 --- a/src/lib/app/hooks/useLoading.jsx +++ b/src/lib/app/hooks/useLoading.jsx @@ -1,10 +1,10 @@ -import { useContext } from "react"; -import { LoadingContext } from "../contexts/loading"; +import {useContext} from "react"; +import {LoadingContext} from "../contexts/loading"; const useLoading = () => { - const { setLoadingPage } = useContext(LoadingContext); + const {setLoadingPage} = useContext(LoadingContext); - return { setLoadingPage }; + return {setLoadingPage}; }; export default useLoading; diff --git a/src/lib/app/hooks/useRequest.js b/src/lib/app/hooks/useRequest.js new file mode 100644 index 0000000..5c567ca --- /dev/null +++ b/src/lib/app/hooks/useRequest.js @@ -0,0 +1,70 @@ +import axios from "axios"; +import {successRequest} from "@/core/utils/succesHandler"; +import PendingNotification from "@/core/components/notifications/PendingNotification"; +import {useTranslations} from "next-intl"; +import useUser from "@/lib/app/hooks/useUser"; +import {errorRequest, errorResponse, errorSetting} from "@/core/utils/errorHandler"; + +const defaultOptions = { + auth: false, + data: {}, + requestOptions: { + headers: {} + }, + notification: true, + pending: true, + success: { + notification: { + show: true, + }, + }, + failed: { + notification: { + show: true, + }, + }, +} +const useRequest = (initOptions) => { + const t = useTranslations() + const {token, clearToken} = useUser() + let _options = {...defaultOptions, ...initOptions} + + function requestServer(url = '', method = 'get', options) { + _options = {..._options, ...options} + if (_options.auth) _options = { + ..._options, + requestOptions: { + ..._options.requestOptions, + headers: {..._options.requestOptions.headers, authorization: `Bearer ${token}`} + } + } + + return new Promise((resolve, reject) => { + if (_options.notification && _options.failed.notification.show && _options.pending) PendingNotification(t) + axios({ + url: url, + method: method, + data: _options.data, + ..._options.requestOptions + }) + .then(response => { + successRequest(response, t, _options) + resolve(response) + }) + .catch(error => { + if (error.response) { + errorResponse(error.response, clearToken, t, _options.notification && _options.failed.notification.show) + } else if (error.request) { + errorRequest(t, _options.notification && _options.failed.notification.show) + } else { + errorSetting(t, _options.notification && _options.failed.notification.show) + } + reject(error) + }) + }); + } + + return requestServer +} + +export default useRequest \ No newline at end of file diff --git a/src/lib/app/hooks/useUser.jsx b/src/lib/app/hooks/useUser.jsx index baa0aaa..21ccbdb 100644 --- a/src/lib/app/hooks/useUser.jsx +++ b/src/lib/app/hooks/useUser.jsx @@ -1,36 +1,36 @@ -import { useContext } from "react"; -import { UserContext } from "../contexts/user"; +import {useContext} from "react"; +import {UserContext} from "../contexts/user"; const useUser = () => { - const { - isAuth, - userChangedLanguage, - token, - user, - getUser, - clearUser, - changeUser, - changeUserLanguage, - changeAuthState, - changeLanguageState, - clearToken, - setToken, - } = useContext(UserContext); + const { + isAuth, + userChangedLanguage, + token, + user, + getUser, + clearUser, + changeUser, + changeUserLanguage, + changeAuthState, + changeLanguageState, + clearToken, + setToken, + } = useContext(UserContext); - return { - isAuth, - userChangedLanguage, - token, - user, - getUser, - clearUser, - changeUser, - changeUserLanguage, - changeAuthState, - changeLanguageState, - clearToken, - setToken, - }; + return { + isAuth, + userChangedLanguage, + token, + user, + getUser, + clearUser, + changeUser, + changeUserLanguage, + changeAuthState, + changeLanguageState, + clearToken, + setToken, + }; }; export default useUser; diff --git a/src/middlewares/UserType.jsx b/src/middlewares/UserType.jsx new file mode 100644 index 0000000..d0b20cc --- /dev/null +++ b/src/middlewares/UserType.jsx @@ -0,0 +1,41 @@ +import {NextLinkComposed} from "@/core/components/LinkRouting"; +import Message from "@/core/components/Messages"; +import useUser from "@/lib/app/hooks/useUser"; +import {Button, Typography} from "@mui/material"; +import {useTranslations} from "next-intl"; + +const UserTypeMiddleware = ({children, user_type}) => { + const {user} = useUser(); + const t = useTranslations(); + + const userPermission = user.type_id === user_type; + + if (!userPermission) { + return ( + + {t("Permission.typography_you_dont_have_access")} + + } + actions={ + <> + + + } + /> + ); + } + + return <>{children}; +}; + +export default UserTypeMiddleware; diff --git a/src/middlewares/WithAuth.jsx b/src/middlewares/WithAuth.jsx index d158bf3..b317492 100644 --- a/src/middlewares/WithAuth.jsx +++ b/src/middlewares/WithAuth.jsx @@ -1,42 +1,41 @@ -import { NextLinkComposed } from "@/core/components/LinkRouting"; +import {NextLinkComposed} from "@/core/components/LinkRouting"; import Message from "@/core/components/Messages"; import useUser from "@/lib/app/hooks/useUser"; -import { Button, Typography } from "@mui/material"; -import { useTranslations } from "next-intl"; -import { useRouter } from "next/router"; +import {Button, Typography} from "@mui/material"; +import {useTranslations} from "next-intl"; +import {useRouter} from "next/router"; -const WithAuthMiddleware = ({ children }) => { - const { isAuth } = useUser(); - const t = useTranslations(); - const router = useRouter(); +const WithAuthMiddleware = ({children}) => { + const {isAuth} = useUser(); + const t = useTranslations(); + const router = useRouter(); - if (!isAuth) - return ( - - {t( - "typography_your_access_to_this_page_has_expired_Please_login_again" - )} - - } - actions={ - <> - - - } - /> - ); - return <>{children}; + if (!isAuth) + return ( + + {t( + "Authorization.typography_your_access_to_this_page_has_expired_Please_login_again" + )} + + } + actions={ + <> + + + } + /> + ); + return <>{children}; }; export default WithAuthMiddleware; diff --git a/src/middlewares/WithoutAuth.jsx b/src/middlewares/WithoutAuth.jsx index 5fb4f93..594ffc5 100644 --- a/src/middlewares/WithoutAuth.jsx +++ b/src/middlewares/WithoutAuth.jsx @@ -1,56 +1,56 @@ import Message from "@/core/components/Messages"; import useUser from "@/lib/app/hooks/useUser"; -import { Stack, Typography } from "@mui/material"; -import { useTranslations } from "next-intl"; -import { useSearchParams } from "next/navigation"; -import { useRouter } from "next/router"; -import { useEffect } from "react"; +import {Stack, Typography} from "@mui/material"; +import {useTranslations} from "next-intl"; +import {useSearchParams} from "next/navigation"; +import {useRouter} from "next/router"; +import {useEffect} from "react"; -const WithoutAuthMiddleware = ({ children }) => { - const { isAuth } = useUser(); - const t = useTranslations(); - const router = useRouter(); +const WithoutAuthMiddleware = ({children}) => { + const {isAuth} = useUser(); + const t = useTranslations(); + const router = useRouter(); - // gettin url query - const searchParams = useSearchParams(); - const backUrlDecodedPath = searchParams.get("back_url"); + // gettin url query + const searchParams = useSearchParams(); + const backUrlDecodedPath = searchParams.get("back_url"); - useEffect(() => { - if (!isAuth) return; - const timer = setTimeout(() => { - router.replace( - backUrlDecodedPath - ? decodeURIComponent(backUrlDecodedPath) - : "/dashboard" - ); - }, 2000); + useEffect(() => { + if (!isAuth) return; + const timer = setTimeout(() => { + router.replace( + backUrlDecodedPath + ? decodeURIComponent(backUrlDecodedPath) + : "/dashboard" + ); + }, 2000); - return () => { - clearTimeout(timer); - }; - }, [isAuth]); + return () => { + clearTimeout(timer); + }; + }, [isAuth]); - if (isAuth) - return ( - - - {t( - "typography_your_login_is_valid_and_you_do_not_need_to_login_again" - )} - - - {t("typography_redirect_to")}{" "} - {backUrlDecodedPath - ? t("typography_routing_previuos_page") - : t("typography_routing_dashbaord_page")} - - - } - /> - ); - return <>{children}; + if (isAuth) + return ( + + + {t( + "Authorization.typography_your_login_is_valid_and_you_do_not_need_to_login_again" + )} + + + {t("Authorization.typography_redirect_to")}{" "} + {backUrlDecodedPath + ? t("Authorization.typography_routing_previuos_page") + : t("Authorization.typography_routing_dashbaord_page")} + + + } + /> + ); + return <>{children}; }; export default WithoutAuthMiddleware; diff --git a/src/pages/403.jsx b/src/pages/403.jsx new file mode 100644 index 0000000..15ba915 --- /dev/null +++ b/src/pages/403.jsx @@ -0,0 +1,24 @@ +import {useEffect, useState} from "react"; +import {useRouter} from "next/router"; +import {NextIntlProvider} from "next-intl"; +import UnAuthorizedComponent from "@/components/errors/403"; + +export default function Custom404() { + const router = useRouter() + const [messages, setMessages] = useState(null) + useEffect(() => { + const fetch = async () => { + const tempMessages = (await import(`&/locales/${router.locale}/app.json`)).default + setMessages(tempMessages) + } + fetch() + }, []); + + if (!messages) return + + return ( + + + + ); +} diff --git a/src/pages/404.jsx b/src/pages/404.jsx new file mode 100644 index 0000000..26de038 --- /dev/null +++ b/src/pages/404.jsx @@ -0,0 +1,25 @@ +import {useEffect, useState} from "react"; +import {useRouter} from "next/router"; +import {NextIntlProvider} from "next-intl"; +import NotFoundComponent from "@/components/errors/404"; + +export default function Custom404() { + const router = useRouter() + const [messages, setMessages] = useState(null) + useEffect(() => { + + const fetch = async () => { + const tempMessages = (await import(`&/locales/${router.locale}/app.json`)).default + setMessages(tempMessages) + } + fetch() + }, []); + + if (!messages) return + + return ( + + + + ); +} diff --git a/src/pages/500.jsx b/src/pages/500.jsx new file mode 100644 index 0000000..4b85bc2 --- /dev/null +++ b/src/pages/500.jsx @@ -0,0 +1,24 @@ +import {useEffect, useState} from "react"; +import {useRouter} from "next/router"; +import {NextIntlProvider} from "next-intl"; +import ServerErrorComponent from "@/components/errors/500"; + +export default function Custom500() { + const router = useRouter() + const [messages, setMessages] = useState(null) + useEffect(() => { + const fetch = async () => { + const tempMessages = (await import(`&/locales/${router.locale}/app.json`)).default + setMessages(tempMessages) + } + fetch() + }, []); + + if (!messages) return + + return ( + + + + ); +} diff --git a/src/pages/_app.jsx b/src/pages/_app.jsx index be5d828..0fc6a4a 100644 --- a/src/pages/_app.jsx +++ b/src/pages/_app.jsx @@ -1,30 +1,32 @@ import "&/fontiran.scss"; import AppLayout from "@/layouts/AppLayout"; import MuiLayout from "@/layouts/MuiLayout"; -import { LanguageProvider } from "@/lib/app/contexts/language"; -import { LoadingProvider } from "@/lib/app/contexts/loading"; -import { UserProvider } from "@/lib/app/contexts/user"; +import {LanguageProvider} from "@/lib/app/contexts/language"; +import {LoadingProvider} from "@/lib/app/contexts/loading"; +import {UserProvider} from "@/lib/app/contexts/user"; import "moment/locale/fa"; -import { NextIntlProvider } from "next-intl"; +import {NextIntlProvider} from "next-intl"; +import TitlePage from "@/core/components/TitlePage"; -const App = ({ Component, pageProps }) => { - return ( - <> - - - - - - - - - - - - - - - ); +const App = ({Component, pageProps}) => { + return ( + <> + + + + + {pageProps.messages ? : ''} + + + + + + + + + + + ); }; export default App; diff --git a/src/pages/_document.jsx b/src/pages/_document.jsx index e763884..c9c28bb 100644 --- a/src/pages/_document.jsx +++ b/src/pages/_document.jsx @@ -1,67 +1,61 @@ -import { - createEmotionCacheLtr -} from "@/core/utils/createEmotionCache"; +import {createEmotionCacheRtl} from "@/core/utils/createEmotionCache"; import theme from "@/core/utils/theme"; import createEmotionServer from "@emotion/server/create-instance"; -import Document, { Head, Html, Main, NextScript } from "next/document"; +import Document, {Head, Html, Main, NextScript} from "next/document"; export default function MyDocument(props) { - const { emotionStyleTags } = props; + const {emotionStyleTags} = props; - return ( - - - - - - - - {emotionStyleTags} - - -
- - - - ); + return ( + + + + + + + {emotionStyleTags} + + +
+ + + + ); } MyDocument.getInitialProps = async (ctx) => { - const originalRenderPage = ctx.renderPage; - let cache; - switch (ctx.locale) { - case "fa": - cache = createEmotionCacheLtr(); - break; - } + const originalRenderPage = ctx.renderPage; + let cache; + switch (ctx.locale) { + case "fa": + cache = createEmotionCacheRtl(); + break; + } - const { extractCriticalToChunks } = createEmotionServer(cache); + const {extractCriticalToChunks} = createEmotionServer(cache); - ctx.renderPage = () => - originalRenderPage({ - enhanceApp: (App) => - function EnhanceApp(props) { - return ; - }, - }); + ctx.renderPage = () => + originalRenderPage({ + enhanceApp: (App) => + function EnhanceApp(props) { + return ; + }, + }); - const initialProps = await Document.getInitialProps(ctx); + const initialProps = await Document.getInitialProps(ctx); - const emotionStyles = extractCriticalToChunks(initialProps.html); - const emotionStyleTags = emotionStyles.styles.map((style) => ( -