diff --git a/.DS_Store b/.DS_Store index d585516..9d4c452 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/.gitignore b/.gitignore index 3d559fe..b32e0bd 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,11 @@ settings/soveliti/soveliti_settings.php assets/database/dev_schema.sql assets/database/migration.sql assets/database/prod_schema.sql +migration.sql +assets/database/migration_triggers.sql +assets/database/migration_v2.sql +assets/database/migration_v3.sql +.DS_Store +api/.DS_Store +api/v1/.DS_Store +api/v2/.DS_Store diff --git a/api/.DS_Store b/api/.DS_Store index 25bea50..362cceb 100644 Binary files a/api/.DS_Store and b/api/.DS_Store differ diff --git a/api/v1/.DS_Store b/api/v1/.DS_Store index cb2f10e..ad7d9dd 100644 Binary files a/api/v1/.DS_Store and b/api/v1/.DS_Store differ diff --git a/api/v2/.DS_Store b/api/v2/.DS_Store index c28ab40..16d8e39 100644 Binary files a/api/v2/.DS_Store and b/api/v2/.DS_Store differ diff --git a/api/v2/get/.DS_Store b/api/v2/get/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/api/v2/get/.DS_Store and /dev/null differ diff --git a/api/v2/get/equipments.php b/api/v2/get/equipments.php index d02c76d..13eb35e 100644 --- a/api/v2/get/equipments.php +++ b/api/v2/get/equipments.php @@ -143,6 +143,10 @@ if(isset($get_content) && $get_content!=''){ $clause .= ' AND e.serialnumber IN (:'.$v[0].')'; } } + elseif ($v[0] == 'validate') { + // Set validation mode flag + $validation_mode = true; + } elseif ($v[0] == 'firmware') { //Assets with firmaware upgrade = 0 (1=latest version, 2=No software) $clause .= ' AND e.status != 5 AND e.sw_version_latest = 0'; @@ -161,7 +165,7 @@ if(isset($get_content) && $get_content!=''){ } } -if ($sw_version_latest_update == 1){ +if ($sw_version_latest_update == 1 || $clause == ''){ //------------------------------------------ //UPDATE SW_STATUS //------------------------------------------ @@ -175,6 +179,10 @@ if (isset($criterias['download']) && $criterias['download'] ==''){ //Request for download $sql = 'SELECT e.rowID as equipmentID, e.*, p.productcode, p.productname from equipment e LEFT JOIN products p ON e.productrowid = p.rowID '.$whereclause.' ORDER BY equipmentID'; } +elseif (isset($validation_mode) && $validation_mode === true) { + // Validation mode - return count only for serial validation + $sql = "SELECT count(rowID) as rowID from equipment e $whereclause"; +} elseif (isset($criterias['totals']) && $criterias['totals'] =='' && !isset($criterias['type'])){ //Request for total rows $sql = 'SELECT count(*) as count from equipment e LEFT JOIN products p ON e.productrowid = p.rowID '.$whereclause.''; @@ -314,7 +322,19 @@ if (debug){ //------------------------------------------ //Add paging details //------------------------------------------ -if(isset($criterias['totals']) && $criterias['totals']==''){ +if (isset($validation_mode) && $validation_mode === true) { + $stmt->execute(); + $messages = $stmt->fetch(); + + if ($messages[0] == 1) { + echo json_encode(array('SN'=> TRUE)); + } + else { + echo json_encode(array('SN'=> FALSE)); + } + return; +} +elseif(isset($criterias['totals']) && $criterias['totals']==''){ $stmt->execute(); $messages = $stmt->fetch(); $messages = $messages[0]; diff --git a/api/v2/get/history.php b/api/v2/get/history.php index be5c826..8967b7c 100644 --- a/api/v2/get/history.php +++ b/api/v2/get/history.php @@ -136,10 +136,22 @@ else { $messages = $stmt->fetchAll(PDO::FETCH_ASSOC); } +// Clean up nested JSON in description fields before final encoding +if (!isset($criterias['totals']) || $criterias['totals'] != '') { + foreach ($messages as &$message) { + if (isset($message['description']) && is_string($message['description'])) { + $decoded = json_decode($message['description'], true); + if (json_last_error() === JSON_ERROR_NONE) { + $message['description'] = json_encode($decoded, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + } + } + } +} + //------------------------------------------ //JSON_ENCODE //------------------------------------------ -$messages = json_encode($messages, JSON_UNESCAPED_UNICODE); +$messages = json_encode($messages, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); //Send results echo $messages; diff --git a/api/v2/get/invoice.php b/api/v2/get/invoice.php index 8091646..07055c6 100644 --- a/api/v2/get/invoice.php +++ b/api/v2/get/invoice.php @@ -51,7 +51,7 @@ elseif (isset($criterias['list']) && $criterias['list'] =='invoice'){ //SQL for Paging $sql = 'SELECT tx.*, txi.item_id as item_id,txi.item_price as item_price, txi.item_quantity as item_quantity, txi.item_options as item_options, p.productcode, p.productname, inv.id as invoice, inv.created as invoice_created, i.language as user_language FROM transactions tx - left join invoice inv ON tx.id = inv.txn_id + left join invoice inv ON tx.txn_id = inv.txn_id left join transactions_items txi ON tx.id = txi.txn_id left join products p ON p.rowID = txi.item_id left join identity i ON i.userkey = tx.account_id '.$whereclause; diff --git a/api/v2/get/software_available.php b/api/v2/get/software_available.php index 3513575..ef5f27f 100644 --- a/api/v2/get/software_available.php +++ b/api/v2/get/software_available.php @@ -161,6 +161,7 @@ if (isset($criterias['sn']) && $criterias['sn'] != ''){ $debug['decision'] = 'No active software assignments found'; } } else { + $available_upgrades = 0; $has_priced_options = false; $has_latest_version_different = false; @@ -242,6 +243,8 @@ if (isset($criterias['sn']) && $criterias['sn'] != ''){ } if ($show_version) { + $available_upgrades++; + //Check if there's a valid license for this upgrade if ($final_price > 0 && $sw_version_license) { //Check if the license is valid @@ -286,23 +289,18 @@ if (isset($criterias['sn']) && $criterias['sn'] != ''){ } } - // Apply the logic: - // 1. If there are priced options -> "yes" - // 2. If no priced options but current version != latest flagged version -> "yes" - // 3. Default -> "no" - if ($has_priced_options) { + // Simple logic: if any upgrades are available to show, return "yes" + if ($available_upgrades > 0) { $software_available = "yes"; - $availability_reason = "Has priced upgrade options available"; - } elseif ($has_latest_version_different) { - $software_available = "yes"; - $availability_reason = "Has free latest version available"; + $availability_reason = "Software upgrades available"; } else { $software_available = "no"; - $availability_reason = "No upgrades available or already on latest"; + $availability_reason = "No upgrades available"; } if (debug) { $debug['final_decision'] = [ + 'available_upgrades' => $available_upgrades, 'has_priced_options' => $has_priced_options, 'has_latest_version_different' => $has_latest_version_different, 'software_available' => $software_available, diff --git a/api/v2/get/software_update.php b/api/v2/get/software_update.php index 2f4696b..6742cd0 100644 --- a/api/v2/get/software_update.php +++ b/api/v2/get/software_update.php @@ -133,6 +133,7 @@ if (isset($criterias['sn']) && $criterias['sn'] != ''){ JOIN products_software_versions psv ON psa.software_version_id = psv.rowID WHERE psa.product_id = ? AND psa.status = 1 + AND psv.latest = 1 AND (psv.hw_version = ? OR psv.hw_version IS NULL OR psv.hw_version = "")'; $stmt = $pdo->prepare($sql); @@ -212,16 +213,13 @@ if (isset($criterias['sn']) && $criterias['sn'] != ''){ $decision_reason = 'Skipped - is current version but no upgrades scenario'; } } else { - //Check if this is the current version and should be shown as disabled - if ($is_current_version && $has_paid_upgrade_from_current && $version['latest'] == 1) { - //Show current version as disabled only if it's the latest AND there's a paid upgrade available + //Check if this is the current version - always show it + if ($is_current_version) { $show_version = true; $is_current = true; $final_price = '0.00'; $final_currency = ''; - $decision_reason = 'Showing as CURRENT - is latest version with paid upgrade available'; - } else if ($is_current_version && !($has_paid_upgrade_from_current && $version['latest'] == 1)) { - $decision_reason = 'Skipped - is current version but not (latest + has_paid_upgrade)'; + $decision_reason = 'Showing as CURRENT - always show current version'; } else if (!$is_current_version) { //Check if this version is part of ANY upgrade path system (either FROM or TO) $sql = 'SELECT COUNT(*) as path_count diff --git a/api/v2/post/.DS_Store b/api/v2/post/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/api/v2/post/.DS_Store and /dev/null differ diff --git a/api/v2/post/history.php b/api/v2/post/history.php index 75eead9..2cbe397 100644 --- a/api/v2/post/history.php +++ b/api/v2/post/history.php @@ -1,5 +1,6 @@ HW; - $sw_version = $test->HEX_FW; + $hw_version = $post_content['payload']['HW']; + $sw_version = $post_content['payload']['HEX_FW']; } else { //GET HW + SW from object diff --git a/api/v2/post/products_software_upgrade_paths.php b/api/v2/post/products_software_upgrade_paths.php index 6b6f9a4..6ce616f 100644 --- a/api/v2/post/products_software_upgrade_paths.php +++ b/api/v2/post/products_software_upgrade_paths.php @@ -14,7 +14,7 @@ $post_content = json_decode($input,true); if (empty($partner->soldto) || $partner->soldto == ''){$soldto_search = '%';} else {$soldto_search = '-%';} //default whereclause -list($whereclause,$condition) = getWhereclauselvl2("software_upgrade_paths",$permission,$partner,''); +list($whereclause,$condition) = getWhereclauselvl2("",$permission,$partner,''); //SET PARAMETERS FOR QUERY $id = $post_content['rowID'] ?? ''; //check for rowID diff --git a/assets/functions.php b/assets/functions.php index 6e50226..ed0e09f 100644 --- a/assets/functions.php +++ b/assets/functions.php @@ -1672,7 +1672,7 @@ function overviewIndicators($warranty, $service, $sw_version, $sw_version_latest $indicator .= 'F'; } else { if ($sw_version == ''){ - $indicator .= 'F'; + $indicator .= 'F'; } else { $indicator .= 'F'; } @@ -1777,7 +1777,7 @@ function availableFirmware($sw_version,$sw_version_latest){ break; default: - $message ='Unknown'; + $message =''; break; } @@ -5339,10 +5339,12 @@ function generateSoftwareInvoice($invoice_data, $order_id, $language = 'US') { $customer_country = $customer['address_country'] ?? ''; // Extract transaction data - $payment_amount = $invoice_data['payment_amount'] ?? 0; - $tax_amount = $invoice_data['tax_amount'] ?? 0; - $shipping_amount = $invoice_data['shipping_amount'] ?? 0; - $discount_amount = $invoice_data['discount_amount'] ?? 0; + $pricing = $invoice_data['pricing'] ?? []; + $payment_amount = $pricing['payment_amount'] ?? $invoice_data['payment_amount'] ?? 0; + $tax_amount = $pricing['tax_total'] ?? $invoice_data['tax_amount'] ?? 0; + $shipping_amount = $pricing['shipping_total'] ?? $invoice_data['shipping_amount'] ?? 0; + $discount_amount = $pricing['discount_total'] ?? $invoice_data['discount_amount'] ?? 0; + $subtotal_amount = $pricing['subtotal'] ?? 0; $currency = 'EUR'; // Default currency $invoice_date = $invoice_data['invoice_created'] ?? date('Y-m-d H:i:s'); @@ -5373,6 +5375,39 @@ function generateSoftwareInvoice($invoice_data, $order_id, $language = 'US') { 'serial_number' => $serial_number, 'license_key' => $license_key ]; + } elseif (isset($invoice_data['products']) && is_array($invoice_data['products'])) { + // New format with products array + $pdo = dbConnect($dbname); + + foreach ($invoice_data['products'] as $product) { + $product_code = $product['productcode'] ?? null; + $product_name = $product['product_name'] ?? null; + $product_options = $product['options'] ?? []; + $product_serial = $product_options['serial_number'] ?? null; + + // Handle case where productcode and product_name are empty but serial_number exists + if ((empty($product_code) || $product_code === null) && + (empty($product_name) || $product_name === null) && + !empty($product_serial)) { + $product_code = 'License'; + $product_name = 'software license for ' . $product_serial; + } + + // Get license key from database + $sql = 'SELECT license_key FROM products_software_licenses WHERE transaction_id = ? LIMIT 1'; + $stmt = $pdo->prepare($sql); + $stmt->execute([$order_id]); + $license_result = $stmt->fetch(PDO::FETCH_ASSOC); + $license_key = $license_result['license_key'] ?? 'Pending'; + + $items[] = [ + 'name' => $product_name ?? 'Software Upgrade', + 'quantity' => $product['quantity'] ?? 1, + 'price' => $product['price'] ?? 0, + 'serial_number' => $product_serial ?? 'N/A', + 'license_key' => $license_key + ]; + } } // Load language translations @@ -5402,127 +5437,319 @@ function generateSoftwareInvoice($invoice_data, $order_id, $language = 'US') { $lbl_license_key = $translations['license_key'] ?? 'License Key'; $lbl_license_expiry = $translations['license_expiry'] ?? 'License Expiry'; + // Subtotal calculation - use from pricing data or calculate from items + if ($subtotal_amount > 0) { + $subtotal = $subtotal_amount; + } else { + // Calculate from items if not provided + $subtotal = 0; + foreach ($items as $item) { + $subtotal += $item['price'] * $item['quantity']; + } + } + // Build HTML invoice $html = ' - + + + ' . htmlspecialchars($lbl_invoice) . ' - Total Safety Solutions -
-
' . htmlspecialchars($lbl_invoice) . '
-
- ' . htmlspecialchars($lbl_invoice_number) . ': ' . htmlspecialchars($order_id) . '
- ' . htmlspecialchars($lbl_invoice_date) . ': ' . htmlspecialchars(date('Y-m-d', strtotime($invoice_date))) . ' + + + +
' . htmlspecialchars($lbl_invoice) . '
+ +
+
+

Total Safety Solutions B.V.

+

Laarakkerweg 8

+

5061 JR OISTERWIJK

+

Nederland

+
+
-
- ' . htmlspecialchars($lbl_customer) . ':
- ' . htmlspecialchars($customer_name) . '
'; - - if ($customer_address) { - $html .= htmlspecialchars($customer_address) . '
'; - } - if ($customer_city || $customer_zip) { - $html .= htmlspecialchars($customer_zip . ' ' . $customer_city) . '
'; - } - if ($customer_state) { - $html .= htmlspecialchars($customer_state) . '
'; - } - if ($customer_country) { - $html .= htmlspecialchars($customer_country) . '
'; - } - - $html .= htmlspecialchars($customer_email) . ' +
+
+
+
Invoice Date
+
: ' . htmlspecialchars(date('d-m-Y', strtotime($invoice_date))) . '
+
+
+
Invoice Number
+
: ' . htmlspecialchars($order_id) . '
+
+
+
+
+
Reference
+
: Online order
+
+
+
Order number
+
: ' . htmlspecialchars($order_id) . '
+
+
- +
- - - + + + + + '; foreach ($items as $item) { + $line_total = $item['price'] * $item['quantity']; $html .= ' - - - - '; + + + + + + '; } - // Subtotal - $subtotal = $payment_amount - $tax_amount - $shipping_amount + $discount_amount; - $html .= ' - - - '; - - // Tax - if ($tax_amount > 0) { - $html .= ' - - - '; - } - - // Shipping - if ($shipping_amount > 0) { - $html .= ' - - - '; - } - - // Discount - if ($discount_amount > 0) { - $html .= ' - - - '; - } - - // Total - $html .= ' - - - '; - $html .= ' -
' . htmlspecialchars($lbl_product) . '' . htmlspecialchars($lbl_quantity) . '' . htmlspecialchars($lbl_price) . 'Item codeDescriptionQuantityPriceTotal
' . htmlspecialchars($item['name']) . '' . htmlspecialchars($item['quantity']) . '' . number_format($item['price'], 2) . ' ' . htmlspecialchars($currency) . '
SOFTWARE' . htmlspecialchars($item['name']); + + if ($item['serial_number'] !== 'N/A') { + $html .= '
Serial: ' . htmlspecialchars($item['serial_number']) . ''; + } + if ($item['license_key'] !== 'Pending') { + $html .= '
License: ' . htmlspecialchars($item['license_key']) . ''; + } + + $html .= '
' . htmlspecialchars($item['quantity']) . ' € ' . number_format($item['price'], 2) . '€ ' . number_format($line_total, 2) . '
' . htmlspecialchars($lbl_subtotal) . ':' . number_format($subtotal, 2) . ' ' . htmlspecialchars($currency) . '
' . htmlspecialchars($lbl_tax) . ':' . number_format($tax_amount, 2) . ' ' . htmlspecialchars($currency) . '
' . htmlspecialchars($lbl_shipping) . ':' . number_format($shipping_amount, 2) . ' ' . htmlspecialchars($currency) . '
' . htmlspecialchars($lbl_discount) . ':-' . number_format($discount_amount, 2) . ' ' . htmlspecialchars($currency) . '
' . htmlspecialchars($lbl_total) . ':' . number_format($payment_amount, 2) . ' ' . htmlspecialchars($currency) . '
'; + - // License information - if ($license_key && $serial_number) { - $html .= '
- Software License Information:
- ' . htmlspecialchars($lbl_device_serial) . ': ' . htmlspecialchars($serial_number) . '
- ' . htmlspecialchars($lbl_license_key) . ': ' . htmlspecialchars($license_key) . '
- ' . htmlspecialchars($lbl_license_expiry) . ': 2099-12-31 -
'; +
+
+
' . htmlspecialchars($lbl_subtotal) . '
+
€ ' . number_format($subtotal, 2) . '
+
'; + + if ($tax_amount > 0) { + $html .= '
+
' . htmlspecialchars($lbl_tax) . '
+
€ ' . number_format($tax_amount, 2) . '
+
'; + } else { + $html .= '
+
VAT
+
included
+
'; } - - $html .= ' + '; diff --git a/assets/images/TSS_invoice_footer.png b/assets/images/TSS_invoice_footer.png new file mode 100644 index 0000000..c6129f5 Binary files /dev/null and b/assets/images/TSS_invoice_footer.png differ diff --git a/assets/images/TSS_invoice_header.png b/assets/images/TSS_invoice_header.png new file mode 100644 index 0000000..aa6ef31 Binary files /dev/null and b/assets/images/TSS_invoice_header.png differ diff --git a/assets/mollie/.DS_Store b/assets/mollie/.DS_Store deleted file mode 100644 index 9c0e967..0000000 Binary files a/assets/mollie/.DS_Store and /dev/null differ diff --git a/assets/mollie/src/.DS_Store b/assets/mollie/src/.DS_Store deleted file mode 100644 index c6ec583..0000000 Binary files a/assets/mollie/src/.DS_Store and /dev/null differ diff --git a/assets/scripts.js b/assets/scripts.js index 28f9696..cb1df5e 100644 --- a/assets/scripts.js +++ b/assets/scripts.js @@ -119,7 +119,10 @@ async function connectDevice() { // Log connection failure details await logCommunication(`Serial connection failed: ${error.message || 'Unknown error'}`, 'disconnected'); - if (openPort = 1){ + // Check for specific "No port selected" error and show user-friendly message + if (error.message && error.message.includes('No port selected by the user')) { + progressBar("100", "No device selected, please try again", "#ff6666"); + } else if (openPort = 1){ closePort(); console.log("Closing port"); alert("System is still trying to close the serial port. If this message continues to come up please refresh this page."); diff --git a/assets/softwaretool.js b/assets/softwaretool.js index 0194de5..5e8a9ac 100644 --- a/assets/softwaretool.js +++ b/assets/softwaretool.js @@ -161,7 +161,13 @@ async function connectDeviceForSoftware() { } catch (error) { await logCommunication(`Connection error: ${error.message}`, 'error'); - progressBar("0", "Error: " + error.message, "#ff6666"); + + // Check for specific "No port selected" error and show user-friendly message + if (error.message && error.message.includes('No port selected by the user')) { + progressBar("100", "No device selected, please try again", "#ff6666"); + } else { + progressBar("100", "Error: " + error.message, "#ff6666"); + } } } @@ -1193,14 +1199,50 @@ async function downloadAndInstallSoftware(option, customerData = null) { console.log("Click the 'Install Software' button to test if upload.js can handle the file"); alert("DEBUG MODE: Download complete!\n\nBlob size: " + blob.size + " bytes\n\nClick the 'Install Software' button to test upload.js"); } else { - // PRODUCTION MODE: Show upload button and automatically trigger + // PRODUCTION MODE: Hide button and show installation in progress document.getElementById("uploadSection").style.display = "block"; const uploadBtn = document.getElementById("uploadSoftware"); - uploadBtn.style.display = "block"; - uploadBtn.disabled = false; + uploadBtn.style.display = "none"; + + // Hide device version information during installation + const softwareOptions = document.getElementById("softwareOptions"); + if (softwareOptions) { + softwareOptions.style.display = "none"; + } + + // Create installation status indicator + const installStatus = document.createElement("div"); + installStatus.id = "installationStatus"; + installStatus.style.cssText = ` + text-align: center; + padding: 20px; + background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); + border-radius: 8px; + margin: 10px 0; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + `; + installStatus.innerHTML = ` + +

Installing Software...

+

Please keep your device connected and do not close this page

+ `; + + // Insert status before the hidden upload section + document.getElementById("uploadSection").parentNode.insertBefore(installStatus, document.getElementById("uploadSection")); - progressBar("60", "Ready to install, starting upload...", "#04AA6D"); - uploadBtn.click(); + progressBar("60", "Starting automatic installation...", "#04AA6D"); + + // Enable the upload button and automatically click it + setTimeout(() => { + uploadBtn.disabled = false; + + // Start monitoring for completion + if (typeof startUploadMonitoring === 'function') { + startUploadMonitoring(); + } + + uploadBtn.click(); + }, 1000); } } catch (error) { diff --git a/custom/bewellwell/settings/bewellwell_settings.php b/custom/bewellwell/settings/bewellwell_settings.php index 8cd76de..1780d98 100644 --- a/custom/bewellwell/settings/bewellwell_settings.php +++ b/custom/bewellwell/settings/bewellwell_settings.php @@ -19,7 +19,7 @@ $color_accent = '#2FAC66'; //'#ececec'; // Database settings //------------------------------------------ -require '/var/www/vhosts/morvalwatches.com/settings/soveliti_cloud_settings.php'; +require '/var/www/vhosts/morvalwatches.com/settings/bewellwell_cloud_settings.php'; //------------------------------------------ // Menusetup & settings diff --git a/custom/morvalwatches/mail/email_template_new.php b/custom/morvalwatches/mail/email_template_new.php new file mode 100644 index 0000000..4760382 --- /dev/null +++ b/custom/morvalwatches/mail/email_template_new.php @@ -0,0 +1,102 @@ + + + + + + ' . $subject . ' + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ '.site_name.' +
+ ' . $newuser_header . ', +
+
+ '.$newuser_text.' '.$newuser_credential_text_1.''.$post_content['username'].' +
+
+ '.$newuser_credential_text_2.' +
+ + + + + +
+ Reset Password +
+
+ ' . $newuser_closure . ' +
+
+ Kind regards, +
+
+ Service team +
+
+
+
+ + +'; \ No newline at end of file diff --git a/custom/morvalwatches/mail/email_template_reset.php b/custom/morvalwatches/mail/email_template_reset.php new file mode 100644 index 0000000..f9fafb4 --- /dev/null +++ b/custom/morvalwatches/mail/email_template_reset.php @@ -0,0 +1,99 @@ + + + + + + ' . $subject . ' + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ '.site_title.' +
+ ' . $changeuser_header . ', +
+
+ '.$changeuser_text.' +
+
+ '.$changeuser_credential_text_1 .' +
+ + + + + +
+ Reset Password +
+
+ ' . $changeuser_closure . ' +
+
+ Kind regards, +
+
+ Service team +
+
+
+
+ + +'; \ No newline at end of file diff --git a/custom/morvalwatches/settings/morvalwatches_config.php b/custom/morvalwatches/settings/morvalwatches_config.php new file mode 100644 index 0000000..8ab12a2 --- /dev/null +++ b/custom/morvalwatches/settings/morvalwatches_config.php @@ -0,0 +1,55 @@ +format('F'); + +//------------------------------------------ +//History Type +//------------------------------------------ +$type1 = 'General'; +$type2 = 'Customer'; +$type3 = 'Service'; +$type4 = 'Testing'; +$type5 = 'Data'; +$type6 = 'Other'; +$type7 = 'Internal'; +$type8 = 'Ignore'; +$type9 = 'Warranty'; +$type10 = 'Contract'; +$type11 = 'Warranty-Expired'; +$type12 = 'Contract-Expired'; +$type13 = "Order"; +$type14 = "ServiceReport"; +$type15 = "SRIncluded"; +$type16 = "Notes"; +$type17 = "Visual"; + +$HistoryType_1 = 'Bootloader'; +$HistoryType_2 = 'Firmware'; +$HistoryType_3 = 'SerialNumber'; +$HistoryType_4 = 'Visual_Test'; +$HistoryType_5 = 'Maintenance_Test'; +$HistoryType_6 = 'Assembly_Test'; +$HistoryType_7 = 'ProductNumber'; +$HistoryType_8 = 'Visual'; +$HistoryType_9 = 'ServiceReport'; +//------------------------------------------ +//Permissions CRUD +//------------------------------------------ +$permission_4 = 'CRUD'; //Admin+ +$permission_3 = 'CRUD'; //Admin +$permission_2 = 'CRU'; //SuperUser +$permission_1 = 'CRU'; //CreateUpdate +$permission_0 = 'R'; //Readonly + +$permissionlabel1 = 'Permission'; +$permission1 = 'Superuser'; #1 +$permission2 = 'Create & Update'; #2 +$permission3 = 'read-only'; // #3 +$permission4 = 'Admin'; //#4 +$permission5 = 'Admin+'; // #5 + +$settingslabel1 = 'profile'; +$setting1 = 'firmware'; //Fix +$setting2 = 'service'; +$setting3 = 'build'; //Fix +$setting4 = 'distribution'; +$setting5 = ''; +$setting6 = ''; +$setting7 = ''; //Fix +$setting8 = 'interface'; + +//------------------------------------------ +//Partners +//------------------------------------------ +$partnertype1 = 'SalesID'; +$partnertype2 = 'SoldTo'; +$partnertype3 = 'ShipTo'; +$partnertype4 = 'Location'; +$partnertype5 = 'Section'; \ No newline at end of file diff --git a/custom/morvalwatches/settings/settingsmenu.php b/custom/morvalwatches/settings/settingsmenu.php new file mode 100644 index 0000000..b7ce39b --- /dev/null +++ b/custom/morvalwatches/settings/settingsmenu.php @@ -0,0 +1,365 @@ + [ + "main_menu" => [ + "url" => "dashboard", + "selected" => "dashboard", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_dashboard" + ] + ], + "sales" => [ + "main_menu" => [ + "url" => "contracts", + "selected" => "contracts", + "icon" => "fa-solid fa-bars", + "name" => "menu_sales" + ], + "accounts" => [ + "url" => "accounts", + "selected" => "accounts", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_sales_accounts" + ], + "catalog" => [ + "url" => "catalog", + "selected" => "catalog", + "icon" => "fa-solid fa-photo-film", + "name" => "menu_catalog" + ], + "contracts" => [ + "url" => "contracts", + "selected" => "contracts", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_sales_contracts" + ], + "orders" => [ + "url" => "orders", + "selected" => "orders", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_sales_orders" + ], + "identity" => [ + "url" => "identity", + "selected" => "identity", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_identity" + ] + ], + "dealers" => [ + "main_menu" => [ + "url" => "dealers", + "selected" => "dealers", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_dealers" + ] + ], + "buildtool" => [ + "main_menu" => [ + "url" => "buildtool", + "selected" => "buildtool", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_build" + ] + ], + "cartests" => [ + "main_menu" => [ + "url" => "cartests", + "selected" => "cartests", + "icon" => "fa-solid fa-car", + "name" => "menu_cartest" + ] + ], + "marketing" => [ + "main_menu" => [ + "url" => "marketing&product_group=Emergency_Plug&product_content=Images", + "selected" => "marketing", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_marketing" + ] + ], + "equipments" => [ + "main_menu" => [ + "url" => "equipments", + "selected" => "assets", + "icon" => "fa-solid fa-database", + "name" => "menu_assets" + ], + "equipments" =>[ + "url" => "equipments", + "selected" => "assets", + "icon" => "fa-solid fa-database", + "name" => "menu_assets" + ], + "servicereports" => [ + "url" => "servicereports", + "selected" => "servicereports", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_service_reports" + ], + "rmas" => [ + "url" => "rmas", + "selected" => "rmas", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_rmas" + ], + "histories" => [ + "url" => "histories", + "selected" => "histories", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_history" + ], + "firmwaretool" => [ + "url" => "firmwaretool", + "selected" => "firmwaretool", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_firmwaretool" + ] , + "equipments_mass_update" => [ + "url" => "equipments_mass_update", + "selected" => "equipments_mass_update", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_equipments_mass_update" + ] + ], + "products" => [ + "main_menu" => [ + "url" => "products&status=1", + "selected" => "products", + "icon" => "fas fa-box-open", + "name" => "menu_products" + ], + "products" => [ + "url" => "products&status=1", + "selected" => "products", + "icon" => "fas fa-box-open", + "name" => "menu_products" + ], + "products_software" => [ + "url" => "products_software_versions", + "selected" => "products_software_versions", + "icon" => "fas fa-box-open", + "name" => "menu_products_software_versions" + ], + "products_attributes" => [ + "url" => "products_attributes", + "selected" => "products_attributes", + "icon" => "fas fa-box-open", + "name" => "menu_products_attributes" + ], + "pricelists" => [ + "url" => "pricelists", + "selected" => "pricelists", + "icon" => "fa-solid fa-coins", + "name" => "menu_pricelists" + ] + ], + "reporting" => [ + "main_menu" => [ + "url" => "report_build", + "selected" => "report_build", + "icon" => "fa-solid fa-magnifying-glass-chart", + "name" => "menu_report_main" + ], + "report_build" => [ + "url" => "report_build", + "selected" => "report_build", + "icon" => "fa-solid fa-magnifying-glass-chart", + "name" => "menu_report_build" + ], + "report_contracts_billing" => [ + "url" => "report_contracts_billing", + "selected" => "report_contracts_billing", + "icon" => "fa-solid fa-magnifying-glass-chart", + "name" => "menu_report_contracts_billing" + ], + "report_healthindex" => [ + "url" => "report_healthindex", + "selected" => "report_healthindex", + "icon" => "fa-solid fa-magnifying-glass-chart", + "name" => "menu_report_healthindex" + ], + "report_usage" => [ + "url" => "report_usage", + "selected" => "report_usage", + "icon" => "fa-solid fa-magnifying-glass-chart", + "name" => "menu_report_usage" + ] + ], + "admin" =>[ + "main_menu" => [ + "url" => "partners", + "selected" => "partners", + "icon" => "fa-solid fa-bars", + "name" => "menu_admin" + ], + "partners" => [ + "url" => "partners", + "selected" => "partners", + "icon" => "fa-solid fa-bars", + "name" => "menu_admin_partners" + ], + "users" => [ + "url" => "users", + "selected" => "users", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_admin_users" + ], + "communications" => [ + "url" => "communications", + "selected" => "communications", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_admin_communications" + ], + "media" => [ + "url" => "media", + "selected" => "media", + "icon" => "fa-solid fa-photo-film", + "name" => "menu_media" + ], + "categories" => [ + "url" => "categories", + "selected" => "categories", + "icon" => "fa-solid fa-photo-film", + "name" => "menu_categories" + ], + "discounts" => [ + "url" => "discounts", + "selected" => "discounts", + "icon" => "fa-solid fa-photo-film", + "name" => "menu_discounts" + ], + "shipping" => [ + "url" => "shipping", + "selected" => "shipping", + "icon" => "fa-solid fa-truck-fast", + "name" => "menu_shipping" + ] + ], + "settings" => [ + "main_menu" => [ + "url" => "settings", + "selected" => "settings", + "icon" => "fas fa-tools", + "name" => "menu_settings" + ], + "config" => [ + "url" => "settings", + "selected" => "settings", + "icon" => "fas fa-tools", + "name" => "menu_config" + ], + "translations" => [ + "url" => "translations", + "selected" => "translations", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_translations" + ], + "uploader" => [ + "url" => "uploader", + "selected" => "uploader", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_uploader" + ], + "logfile" => [ + "url" => "logfile", + "selected" => "logfile", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_logfile" + ], + "maintenance" => [ + "url" => "maintenance", + "selected" => "maintenance", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_maintenance" + ], + "profiles" => [ + "url" => "profiles", + "selected" => "profiles", + "icon" => "fas fa-tachometer-alt", + "name" => "menu_profiles" + ] + ] +]; + +$routes = array( + '/' => 'equipments.php', + 'equipments' => 'equipments.php', + 'products' => 'products.php', + 'logout' => 'logout.php' +); + +//------------------------------------------ +// Paging +//------------------------------------------ +$page_rows_equipment = 25; //list Equipment +$page_rows_history = 15; //list History +$page_rows_products = 25;//list producst +$page_rows_users = 15;//list users +$page_rows_partners = 15;//list partners +$page_rows_communication = 25; //list communications +$page_rows_accounts = 25 ;// list accounts +$page_rows_contracts = 25 ;// list contracts +$page_rows_cartest = 25 ;// list contracts +$page_rows_equipment_servicereporst = 5 ;// Number of service reports on equipment +$page_rows_changelog = 50 ;// Number of changelogs returned +$page_rows_rma = 25; // list RMA +$page_rows_translations = 50; //list translation variables +$page_rows_products_attributes = 50; //list product attributes +$page_rows_media = 25; // list media +$page_rows_pricelists = 50;//pricelists +$page_rows_categories = 25;//categories +$page_rows_discounts = 25;//discounts +$page_rows_shipping = 25;//discounts +$page_rows_transactions = 25; //transactions +$page_rows_invoice = 25; //invoices +$page_rows_dealers = 25; //dealers +$page_rows_software_versions = 50; //software versions + +//------------------------------------------ +// Languages supported +//------------------------------------------ +$supportedLanguages = ['US', 'NL', 'DE', 'ES','PT']; + +//------------------------------------------ +// Pricing +//------------------------------------------ +$supportedCurrencies = ["0" =>"euro", "1"=>"dollar"]; + +$supportedModifiers = ["0" =>"subtract", "1"=>"add"]; + +// +++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// All individual views and APIs - Profile ++++++++++++++ +// +++++++++++++++++++++++++++++++++++++++++++++++++++++++ +$all_profiles = [ + "build", + "commerce", + "distribution", + "firmware", + "garage", + "interface", + "service", + "other" +]; + +// +++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Marketing +++++++++++++++++++++++++++++++++++++ +// +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +$main_marketing_dir = './marketing/'; + +$marketing_structure = array( +"Emergency_Plug" => array( + "Documents", + "Images", + "Video" + ) + ); \ No newline at end of file diff --git a/custom/morvalwatches/settings/settingsprofiles.php b/custom/morvalwatches/settings/settingsprofiles.php new file mode 100644 index 0000000..2999088 --- /dev/null +++ b/custom/morvalwatches/settings/settingsprofiles.php @@ -0,0 +1,27 @@ + \ No newline at end of file diff --git a/custom/morvalwatches/style/SoVeLiTi.png b/custom/morvalwatches/style/SoVeLiTi.png new file mode 100644 index 0000000..5572acc Binary files /dev/null and b/custom/morvalwatches/style/SoVeLiTi.png differ diff --git a/custom/morvalwatches/style/VeLiTi-Logo2.png b/custom/morvalwatches/style/VeLiTi-Logo2.png new file mode 100755 index 0000000..ea68b1b Binary files /dev/null and b/custom/morvalwatches/style/VeLiTi-Logo2.png differ diff --git a/custom/morvalwatches/style/VeLiTi.png b/custom/morvalwatches/style/VeLiTi.png new file mode 100644 index 0000000..16e9476 Binary files /dev/null and b/custom/morvalwatches/style/VeLiTi.png differ diff --git a/custom/morvalwatches/style/morvalwatches_login.css b/custom/morvalwatches/style/morvalwatches_login.css new file mode 100644 index 0000000..1c0c2fb --- /dev/null +++ b/custom/morvalwatches/style/morvalwatches_login.css @@ -0,0 +1,231 @@ +:root { + --color-white: #FFFFFF; + --color-light-blue: #344fd5c2; + --color-blue: #0b1054; + --color-red: #a75151; + --text-color: #333333; + --error-background: #f3c3c3; +} + + +* { + padding: 0; + margin: 0; + box-sizing: border-box; + font-family: "Open Sans", Helvetica, sans-serif; + accent-color: var(--color-blue); +} + +body { + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + background-color: var(--color-white); + padding: 20px; +} + +.login-container { + display: flex; + width: 100%; + max-width: 1200px; + height: calc(100vh - 40px); + background-color: var(--color-white); + border-radius: 16px; + box-shadow: 0 10px 25px rgba(0,0,0,0.1); + overflow: hidden; +} + +.login-form { + width: 45%; + padding: 40px; + display: flex; + flex-direction: column; + justify-content: center; + position: relative; +} + +.logo { + position: absolute; + top: 20px; + left: 20px; + background-image: url(VeLiTi-Logo2.png); + background-repeat: no-repeat; + opacity: inherit; + width: 85px; + height: 120px; + margin: 0 auto; + -webkit-filter: drop-shadow(5px 5px 5px #222); + filter: drop-shadow(5px 5px 5px #222); +} + +.login-visual { + width: 55%; + position: relative; + overflow: hidden; + background-image: url(veliti_intro.png); + background-position: center center; + background-size: 100% 100%; + background-color: var(--color-light-blue); + background-repeat: no-repeat; +} + +.login-visual img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.register-link { + position: absolute; + top: 20px; + right: 20px; + text-decoration: none; + color: var(--text-color); +} + +.header { + margin-bottom: 30px; +} + +.header h1 { + font-size: 24px; + margin-bottom: 10px; +} + +.header p { + color: #666; +} + +.input-group { + margin-bottom: 15px; + position: relative; +} + +.input-group input { + width: 100%; + padding: 10px; + border: 1px solid #ddd; + border-radius: 4px; +} + +.input-group input[type="email"] { + padding-left: 40px; + background: url('data:image/svg+xml;utf8,') no-repeat left 10px center; +} + +.input-group input[type="password"] { + padding-left: 40px; + background: url('data:image/svg+xml;utf8,') no-repeat left 10px center; +} + +.forgot-password { + color: var(--text-color); + text-decoration: none; + text-align: right; + margin-top: 5px; + float: right; + font-size: 12px; +} + +.remember-me { + display: flex; + align-items: center; + margin-bottom: 20px; +} + +.remember-me input { + margin-right: 10px; +} + +.maintenance { + padding: 5px; +} + +.message p { + margin-top: 5px; + background-color: var(--error-background); + border-left: 4px solid var(--color-red); + color: var(--color-red); + padding: 5px; + border-radius: 4px; + text-align: center; +} + +.login-btn { + width: 100%; + padding: 12px; + background-color: var(--color-light-blue); + color: var(--color-white); + border: none; + border-radius: 4px; + cursor: pointer; + transition: background-color 0.3s ease; +} + +.login-btn:hover { + background-color: var(--color-blue); +} + +.trademark { + position: absolute; + bottom: 20px; + left: 20px; + color: var(--text-color); + font-size: 12px; +} + +.language-selector { + position: absolute; + bottom: 20px; + right: 20px; + display: flex; + align-items: center; + color: var(--text-color); +} + +.language-selector select { + margin-left: 10px; + border: none; + background: transparent; +} + +/* Responsive Design */ +@media screen and (max-width: 1024px) { + .login-container { + flex-direction: column; + height: auto; + max-width: 500px; + } + + .login-form, .login-visual { + width: 100%; + height: auto; + } + + .login-visual { + height: 300px; + } + + .logo { + position: static; + margin: 20px auto; + margin-bottom: 0; + } + + .trademark, .language-selector { + position: static; + text-align: center; + margin: 20px 0; + } +} + +@media screen and (max-width: 480px) { + .login-form { + padding: 20px; + } + + .header h1 { + font-size: 20px; + } +} \ No newline at end of file diff --git a/custom/morvalwatches/style/morvalwatches_reset.css b/custom/morvalwatches/style/morvalwatches_reset.css new file mode 100644 index 0000000..a88f437 --- /dev/null +++ b/custom/morvalwatches/style/morvalwatches_reset.css @@ -0,0 +1,231 @@ +:root { + --color-white: #FFFFFF; + --color-light-blue: #344fd5c2; + --color-blue: #0b1054; + --color-red: #a75151; + --text-color: #333333; + --error-background: #f3c3c3; +} + + +* { + padding: 0; + margin: 0; + box-sizing: border-box; + font-family: "Open Sans", Helvetica, sans-serif; + accent-color: var(--color-blue); +} + +body { + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + background-color: var(--color-white); + padding: 20px; +} + +.login-container { + display: flex; + width: 100%; + max-width: 1200px; + height: calc(100vh - 40px); + background-color: var(--color-white); + border-radius: 16px; + box-shadow: 0 10px 25px rgba(0,0,0,0.1); + overflow: hidden; +} + +.login-form { + width: 45%; + padding: 40px; + display: flex; + flex-direction: column; + justify-content: center; + position: relative; +} + +.logo { + position: absolute; + top: 20px; + left: 20px; + background-image: url(VeLiTi-Logo2.png); + background-repeat: no-repeat; + opacity: inherit; + width: 85px; + height: 120px; + margin: 0 auto; + -webkit-filter: drop-shadow(5px 5px 5px #222); + filter: drop-shadow(5px 5px 5px #222); +} + +.login-visual { + width: 55%; + position: relative; + overflow: hidden; + background-image: url(veliti_intro.png); + background-position: center center; + background-size: 100% 100%; + background-color: var(--color-light-blue); + background-repeat: no-repeat; +} + +.login-visual img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.register-link { + position: absolute; + top: 20px; + right: 20px; + text-decoration: none; + color: var(--text-color); +} + +.header { + margin-bottom: 30px; +} + +.header h1 { + font-size: 24px; + margin-bottom: 10px; +} + +.header p { + color: #666; +} + +.input-group { + margin-bottom: 15px; + position: relative; +} + +.input-group input { + width: 100%; + padding: 10px; + border: 1px solid #ddd; + border-radius: 4px; +} + +.input-group input[type="email"] { + padding-left: 40px; + background: url('data:image/svg+xml;utf8,') no-repeat left 10px center; +} + +.input-group input[type="password"] { + padding-left: 40px; + background: url('data:image/svg+xml;utf8,') no-repeat left 10px center; +} + +.forgot-password { + color: var(--text-color); + text-decoration: none; + text-align: right; + margin-top: 5px; + float: right; + font-size: 12px; +} + +.remember-me { + display: flex; + align-items: center; + margin-bottom: 20px; +} + +.remember-me input { + margin-right: 10px; +} + +.maintenance { + padding: 5px; +} + +.message p { + margin-top: 5px; + background-color: var(--error-background); + border-left: 4px solid var(--color-red); + color: var(--color-red); + padding: 5px; + border-radius: 4px; + text-align: center; +} + +.login-btn { + width: 100%; + padding: 12px; + background-color: var(--color-light-blue); + color: var(--color-white); + border: none; + border-radius: 4px; + cursor: pointer; + transition: background-color 0.3s ease; +} + +.login-btn:hover { + background-color: var(--color-blue); +} + +.trademark { + position: absolute; + bottom: 20px; + left: 20px; + color: var(--text-color); + font-size: 12px; +} + +.language-selector { + position: absolute; + bottom: 20px; + right: 20px; + display: flex; + align-items: center; + color: var(--text-color); +} + +.language-selector select { + margin-left: 10px; + border: none; + background: transparent; +} + +/* Responsive Design */ +@media screen and (max-width: 1024px) { + .login-container { + flex-direction: column; + height: auto; + max-width: 500px; + } + + .login-form, .login-visual { + width: 100%; + height: auto; + } + + .login-visual { + height: 300px; + } + + .logo { + position: static; + margin: 20px auto; + margin-bottom: 0; + } + + .trademark, .language-selector { + position: static; + text-align: center; + margin: 20px 0; + } +} + +@media screen and (max-width: 480px) { + .login-form { + padding: 20px; + } + + .header h1 { + font-size: 20px; + } +} \ No newline at end of file diff --git a/custom/morvalwatches/style/soveliti.css b/custom/morvalwatches/style/soveliti.css new file mode 100644 index 0000000..0ed2857 --- /dev/null +++ b/custom/morvalwatches/style/soveliti.css @@ -0,0 +1,2971 @@ +:root { + --color-text-default: #555555; + --color-text-heading: #4a5361; + --color-bg-body: #fff; + --color-bg-body: #ffffff; + --color-bg-header: #F8f9fa; + --color-bg-header: #f8f9fa; + --color-border-light: #eee; + --color-hover-dark: #606c7e; + --color-hover-light: #fbfbfb; + --color-note-bg: #383c46; + --color-note-text: #afb1b5; + --color-selected-bg: #527ee5; + --color-sub-hover: #2a374a; + --color-title-muted: #959faf; + --color-title-muted-light: #99999a; + --color-title-bg: #dbdddf; + --color-icon-bg: #7c8394; + --color-msg-success-bg: #C3F3D7; + --color-msg-success: #51a775; + --color-msg-error-bg: #f3c3c3; + --color-msg-error: #a75151; + --color-border-input: #d0d3d5; + --color-border-input-hover: #b5b9bd; + --color-filter-text-hover: #343a44; + --color-btn-bg: #4a79b4; + --color-btn-hover-bg: #4672a9; + --color-tab-bg: #dedfe1; + --color-tab-hover: #d8dadc; + --color-muted: #8d9398; + --color-status-neutral: #81848a; + --color-status-enabled: #13b368; + --color-status-warning: #eb8a0d; + --color-status-disabled: #bd4141; + --color-danger: #e26060; + --color-btn-secondary: #bed4ea; + --color-btn-neutral: #f1f3f4; + --color-pagination-hover: #6d7c90; + --color-pagination-bg: #758497; + --color-accent-blue: #0060ba; + --color-accent-blue-hover: #003260; + --color-accent-red: #ba0000; + --color-accent-red-hover: #600000; + --color-disabled: #b1b3b4; + --color-disabled-hover: #a9abad; +} + +* { + box-sizing: border-box; + font-family: -apple-system, BlinkMacSystemFont, "segoe ui", roboto, oxygen, ubuntu, cantarell, "fira sans", "droid sans", "helvetica neue", Arial, sans-serif; + font-size: 16px; +} + +html { + height: 100%; +} + +body { + position: relative; + min-height: 100%; + color: var(--color-text-default); + background-color: var(--color-bg-body); + margin: 0; +} + +h1, h2, h3, h4, h5 { + color: var(--color-text-heading); + margin: 0; + padding: 0; +} + +header { + display: flex; + position: fixed; + top: 0; + left: 0; + padding-left: 260px; + z-index: 999; + width: 100%; + height: 55px; + background-color: var(--color-bg-header); + box-shadow: 0px 0px 4px 1px rgba(0, 0, 0, 0.15); +} + +header a { + display: inline-flex; + color: var(--color-text-heading); + height: 100%; + text-decoration: none; + justify-content: center; + align-items: center; + padding: 0 20px; +} + +header a i { + font-size: 16px; +} + +header a:hover, header a:active { + color: var(--color-hover-dark); +} + +header .space-between { + flex: 1; +} + +header .dropdown { + display: inline-flex; + color: var(--color-text-heading); + height: 100%; + cursor: pointer; + justify-content: center; + align-items: center; + padding: 0 30px; +} + +header .dropdown i { + font-size: 18px; +} + +header .dropdown:hover, header .dropdown:active { + color: var(--color-hover-dark); +} + +header .dropdown .list { + display: none; + position: absolute; + top: 100%; + right: 0; + width: 150px; + background-color: var(--color-bg-body); + border-top: 1px solid var(--color-border-light); + box-shadow: 0px 2px 2px 1px rgba(0, 0, 0, 0.05); +} + +header .dropdown .list a { + padding: 10px 15px; + font-size: 14px; +} + +header .dropdown .list a:hover { + background-color: var(--color-hover-light); +} + +header .dropdown:hover .list, header .dropdown:active .list { + display: flex; + flex-flow: column; +} + +header.full { + padding-left: 0; +} + +aside { + position: fixed; + z-index: 999999; + height: 100%; + width: 260px; + display: flex; + flex-flow: column; + background-color: var(--color-bg-header); + overflow-y: auto; +} + +aside h1 { + background: url("SoVeLiTi.png"); + background-position: center center; + background-repeat: no-repeat; + background-size: 50%; + padding: 30px; +} + +aside > a { + font-size: 14px; + font-weight: 600; + text-decoration: none; + color: var(--color-note-text); + padding: 15px 20px; +} + +aside > a i { + color: inherit; + width: 40px; +} + +aside > a:hover, aside > a.selected { + background-color: var(--color-selected-bg); + color: var(--color-bg-body); + padding: 15px 17px; + border-radius: 5px; +} + +aside > a.selected + .sub { + display: flex; +} + +aside > a .note { + background-color: var(--color-note-bg); + padding: 1px 5px; + border-radius: 4px; + font-size: 12px; + margin-left: 10px; +} + +aside .sub { + display: none; + flex-flow: column; + background-color: var(--color-bg-header); + padding: 13px 0; +} + +aside .sub a { + font-size: 14px; + color: var(--color-note-text); + text-decoration: none; + padding: 4px 20px; +} + +aside .sub a span { + display: inline-block; + width: 40px; + font-size: 12px; +} + +aside .sub a:hover, aside .sub a.selected { + color: var(--color-sub-hover); +} + +aside .footer { + display: flex; + flex-flow: column; + margin-top: auto; + padding: 15px; + font-size: 14px; + color: var(--color-note-text); +} + +aside .footer a { + text-decoration: none; + font-size: 14px; + color: var(--color-note-text); + padding-bottom: 2px; +} + +aside .footer a:hover { + color: #7c7f83; +} + +aside.closed { + display: none; +} + +main { + padding: 30px; + padding-left: 290px; + padding-top: 85px; +} + +main.full { + padding-left: 30px; + padding-right: 30px; +} + +main h2 { + font-size: 20px; + padding-bottom: 20px; + font-weight: 600; +} + +main h2 span { + font-size: 16px; + margin-left: 5px; + font-weight: 600; + color: var(--color-title-muted); +} + +main .content-title { + border-bottom: 1px solid var(--color-title-bg); + display: flex; +} + +main .content-title h2 { + flex: 1; +} + +main .content-title .btn { + height: 36px; +} + +main .content-title .title { + flex: 1; + display: flex; + align-items: center; + padding-bottom: 15px; +} + +main .content-title .title i { + display: inline-flex; + justify-content: center; + align-items: center; + background-color: var(--color-selected-bg); + color: var(--color-bg-body); + width: 52px; + height: 42px; + border-radius: 4px; + margin-right: 12px; +} + +main .content-title .title i.alt { + background-color: var(--color-icon-bg); +} + +main .content-title .title h2 { + padding: 0 0 3px 0; +} + +main .content-title .title p { + margin: 0; + font-size: 14px; + color: var(--color-title-muted-light); + font-weight: 500; +} + +main .msg { + display: flex; + align-items: center; + margin: 15px 0 0 0; + padding: 15px; + font-weight: 500; + box-shadow: 0px 0px 2px 0px rgba(0, 0, 0, 0.1); +} + +main .msg p { + margin: 0; + padding: 0 15px; + font-size: 14px; + flex: 1; +} + +main .msg i.fa-times { + align-self: flex-end; + justify-content: flex-end; + cursor: pointer; +} + +main .msg i.fa-times:hover { + opacity: .9; +} + +main .msg.success { + background-color: #c3f3d7; + border-left: 4px solid var(--color-msg-success); + color: var(--color-msg-success); +} + +main .msg.success i { + color: var(--color-msg-success); +} + +main .msg.error { + background-color: var(--color-msg-error-bg); + border-left: 4px solid var(--color-msg-error); + color: var(--color-msg-error); +} + +main .msg.error i { + color: var(--color-msg-error); +} + +main .content-header { + display: flex; + justify-content: space-between; +} + +main .content-header form { + display: flex; + justify-content: space-between; +} + +main .content-header form .search input, main .content-header form > select { + background-color: transparent; + outline: none; + border: none; + height: 40px; + width: 220px; + border-bottom: 1px solid var(--color-border-input); + padding-right: 25px; + margin-left: 10px; +} + +main .content-header form .search input:hover, main .content-header form .search input:active, main .content-header form > select:hover, main .content-header form > select:active { + border-bottom: 1px solid var(--color-border-input-hover); +} + +main .content-header form > select { + width: 150px; +} + +main .content-header form > a { + text-decoration: none; + display: inline-flex; + color: #676d72; + justify-self: center; + align-items: center; + padding: 0 5px; +} + +main .content-header form > a:hover { + color: #4f5357; +} + +main .content-header .search label { + position: relative; +} + +main .content-header .search i { + position: absolute; + right: 4px; + top: 4px; + bottom: 0; + font-size: 14px; + margin-top: auto; + margin-bottom: auto; + color: var(--color-border-input-hover); +} + +main .content-header .filters { + display: flex; + position: relative; + margin-right: 10px; + margin-bottom: 3px; + align-items: center; +} + +main .content-header .filters a { + text-decoration: none; + font-weight: 600; + color: var(--color-text-heading); + white-space: nowrap; +} + +main .content-header .filters a:hover { + color: var(--color-filter-text-hover); +} + +main .content-header .filters .list { + display: none; + top: calc(100% + 5px); + width: 180px; + flex-flow: column; + position: absolute; + background-color: var(--color-bg-body); + padding: 10px; + box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.1); +} + +main .content-header .filters .list label { + padding-bottom: 5px; + font-size: 14px; +} + +main .content-header .filters .list input { + margin-right: 10px; +} + +main .content-header .filters .list select { + width: 100%; + margin-bottom: 10px; + font-size: 14px; + padding: 3px; + border: 1px solid var(--color-tab-bg); +} + +main .content-header .filters .list button { + background: var(--color-btn-bg); + border: 0; + color: var(--color-bg-body); + padding: 5px 0; + font-size: 12px; + font-weight: 600; + margin-top: 5px; + cursor: pointer; + border-radius: 4px; +} + +main .content-header .filters .list button:hover { + background: var(--color-btn-hover-bg); +} + + +main .content-header .sort { + display: flex; + position: relative; + margin-right: 10px; + margin-bottom: 3px; + align-items: center; +} + +main .content-header .sort a { + text-decoration: none; + font-weight: 600; + color: var(--color-text-heading); + white-space: nowrap; +} + +main .content-header .sort a:hover { + color: var(--color-filter-text-hover); +} + +main .content-header .sort .list { + display: none; + top: calc(100% + 5px); + width: 180px; + flex-flow: column; + position: absolute; + background-color: var(--color-bg-body); + padding: 10px; + box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.1); +} + +main .content-header .sort .list label { + padding-bottom: 5px; + font-size: 14px; +} + +main .content-header .sort .list input { + margin-right: 10px; +} + +main .content-header .sort .list select { + width: 100%; + margin-bottom: 10px; + font-size: 14px; + padding: 3px; + border: 1px solid var(--color-tab-bg); +} + +main .content-header .sort .list button { + background: var(--color-btn-bg); + border: 0; + color: var(--color-bg-body); + padding: 5px 0; + font-size: 12px; + font-weight: 600; + margin-top: 5px; + cursor: pointer; + border-radius: 4px; +} + +main .content-header .sort .list button:hover { + background: var(--color-btn-hover-bg); +} + +main .content-block { + background-color: var(--color-bg-body); + margin-top: 25px; + padding: 15px; + box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.03); + overflow: hidden; + border-radius: 3px; +} + +main .content-block .block-header { + position: relative; + border-bottom: 1px solid #f0f1f2; + margin-bottom: 20px; + padding: 0 15px 15px 15px; + margin-left: -15px; + margin-right: -15px; + font-size: 14px; + font-weight: 500; +} + +main .content-block .block-header i { + display: inline-flex; + height: 25px; + width: 25px; + padding-top: 2px; + justify-content: center; + align-items: center; + border-radius: 50%; + background-color: var(--color-selected-bg); + color: var(--color-bg-body); + margin-right: 10px; +} + +main .content-block-wrapper { + display: flex; + width: 100%; + padding-top: 25px; +} + +main .content-block-wrapper .content-block { + width: 100%; + margin: 0 10px; + border-radius: 3px; +} + +main .content-block-wrapper .content-block:first-child { + margin-left: 0; +} + +main .content-block-wrapper .content-block:last-child { + margin-right: 0; +} + +main .tabs { + display: flex; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + background-color: var(--color-tab-bg); + margin-top: 25px; + box-shadow: 0px 0px 4px 1px rgba(0, 0, 0, 0.03); + z-index: 100; +} + +main .tabs a { + display: flex; + text-decoration: none; + padding: 12px 15px; + border: 0; + color: #6b788c; + font-weight: 500; + font-size: 14px; +} + +main .tabs a:hover { + background-color: var(--color-tab-hover); +} + +main .tabs a.active { + color: var(--color-text-heading); + background-color: var(--color-bg-body); +} + +main .tabs ~ .content-block { + margin-top: 0; + box-shadow: 0px 6px 5px 1px rgba(0, 0, 0, 0.03); +} + +main .tab-content { + display: none; +} + +main .tab-content.active { + display: block; +} + +main .dashboard { + display: flex; + justify-content: space-between; + padding-bottom: 40px; +} + +main .dashboard .stat { + width: 24%; + padding: 0; + display: flex; + flex-flow: wrap; + border-radius: 3px; +} + +main .dashboard .stat > i { + display: inline-flex; + justify-content: center; + padding: 15px; + margin: 30px 25px 0 0; + align-items: center; + font-size: 18px; + height: 40px; + width: 40px; + border-radius: 5px; + background-color: var(--color-selected-bg); + color: var(--color-bg-body); +} + +main .dashboard .stat .data { + padding: 7px; + flex: 1; +} + +main .dashboard .stat .data h3 { + font-size: 16px; + font-weight: 400; + padding: 15px 15px 0 15px; +} + +main .dashboard .stat .data p { + margin: 0; + padding: 10px 15px 15px 15px; + font-size: 24px; + font-weight: 700; +} + +main .dashboard .stat .footer { + width: 100%; + border-top: 1px solid #ebeced; + background-color: var(--color-hover-light); + color: #9aa0a5; + font-size: 14px; + padding: 10px; +} + +main .dashboard .stat .footer i { + padding-right: 5px; +} + +main .form { + display: flex; + flex-flow: column; + padding: 20px; +} + +main .form input[type="text"], main .form input[type="password"], main .form input[type="datetime-local"], main .form input[type="email"], main .form input[type="number"], main .form textarea, main .form select { + width: 100%; + padding: 15px 5px; + margin-bottom: 25px; + border: 0; + border-bottom: 1px solid var(--color-tab-bg); +} + +main .form input[type="text"]:hover, main .form input[type="text"]:active, main .form input[type="password"]:hover, main .form input[type="password"]:active, main .form input[type="datetime-local"]:hover, main .form input[type="datetime-local"]:active, main .form input[type="email"]:hover, main .form input[type="email"]:active, main .form input[type="number"]:hover, main .form input[type="number"]:active, main .form textarea:hover, main .form textarea:active, main .form select:hover, main .form select:active { + border-bottom: 1px solid var(--color-border-input-hover); +} + +main .form textarea { + height: 200px; +} + +main .form input[type="checkbox"] { + width: auto; + margin: 15px 0 25px 2px; + transform: scale(1.2); +} + +main .form label { + display: block; + font-weight: 600; +} + +main .form label .required { + font-style: normal; + color: var(--color-danger); +} + +main .form button { + background-color: var(--color-tab-bg); + color: #676d72; + border: 0; + padding: 5px; + width: 100%; + font-weight: 600; + font-size: 14px; + cursor: pointer; +} + +main .form button:hover { + background-color: #d6d8da; +} + +main .form .multiselect { + position: relative; + display: flex; + flex-flow: wrap; + border-bottom: 1px solid var(--color-tab-bg); + padding-bottom: 10px; + margin: 15px 0 25px 0; + margin-bottom: 25px; +} + +main .form .multiselect > .item { + display: inline-flex; + border: 1px solid var(--color-tab-bg); + padding: 0 10px; + height: 40px; + margin: 0 5px 5px 0; + font-size: 14px; + justify-content: center; + align-items: center; +} +main .multiselect > .item { + display: inline-flex; + border: 1px solid var(--color-tab-bg); + padding: 0 10px; + height: 40px; + margin: 0 5px 5px 0; + font-size: 14px; + justify-content: center; + align-items: center; +} + +main .form .multiselect > .item .remove { + font-style: normal; + cursor: pointer; + font-size: 19px; + margin-right: 3px; + margin-top: -2px; + color: var(--color-border-input-hover); +} + +main .form .multiselect > .item .remove:hover { + color: #9aa0a5; +} + +main .form .multiselect input { + height: 40px; + width: 80px; + flex-grow: 1; + padding: 0; + margin: 0; + outline: 0; + border: 0; +} + +main .form .multiselect input:hover { + border: 0; +} + +main .form .multiselect .list { + display: none; + position: absolute; + top: 100%; + width: 100%; + flex-flow: column; + background-color: var(--color-bg-body); + box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.1); + max-height: 100px; + overflow-y: auto; + z-index: 1000000000; +} + +main .form .multiselect .list span { + display: flex; + padding: 5px 7px; + cursor: pointer; +} + +main .form .multiselect .list span:hover { + background-color: #f3f4f4; +} + +main .form .multiselect:hover, main .form .multiselect:active { + border-bottom: 1px solid var(--color-border-input-hover); +} + +main .top-nav { + display: flex; + flex-flow: wrap; + padding-top: 20px; +} + +main .error { + padding: 15px; + margin: 0; +} + +main .pagination { + display: flex; + align-items: center; + padding: 25px 0; +} + +main .pagination a { + display: inline-flex; + text-decoration: none; + background-color: var(--color-pagination-bg); + font-size: 14px; + font-weight: 600; + color: var(--color-bg-body); + border-radius: 4px; + padding: 7px 10px; +} + +main .pagination a:hover { + background-color: var(--color-pagination-hover); +} + +main .pagination a:first-child { + margin-right: 10px; +} + +main .pagination a:last-child { + margin-left: 10px; +} + +main .pagination span { + font-weight: 600; + margin: 10px; +} + +main .media-page .media { + display: flex; + flex-flow: wrap; + padding: 15px; +} + +main .media-page .media .image { + position: relative; + text-decoration: none; + border: 1px solid #e3e4e6; + padding: 10px; + width: 150px; + height: 135px; + margin: 0 15px 50px 0; +} + +main .media-page .media .image img { + width: 100%; + height: 100%; + object-fit: contain; + transition: all ease .3s; +} + +main .media-page .media .image::after { + content: attr(data-title); + display: block; + position: absolute; + color: #6e7581; + font-size: 14px; + font-weight: 500; + top: calc(100% + 5px); + left: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: 100%; +} + +main .media-page .media .image:hover { + border: 1px solid var(--color-border-input); +} + +main .media-page .media .image:hover img { + transform: scale(1.05); +} + +main .media-page .media .image:hover .title { + color: #5c6471; +} + +main .order-details .order-detail { + display: flex; + justify-content: space-between; + padding-bottom: 15px; + word-break: break-all; +} + +main .order-details .order-detail h3 { + padding: 0; + margin: 0; + font-size: 14px; + font-weight: 500; +} + +main .order-details .order-detail p { + padding: 0; + margin: 0; +} + +main .order-table { + margin: 0; +} + +main .order-table .item-list-end { + border-bottom: 1px solid #f0f1f2; +} + +main .order-table .subtotal { + padding-top: 20px; +} + +main .order-table .subtotal, main .order-table .shipping, main .order-table .total { + text-align: right; + font-weight: 500; + font-size: 14px; +} + +main .order-table .num { + text-align: right; +} + +main .manage-order-table input, main .manage-order-table select { + border: 0; + padding: 5px 0; + height: 40px; + background: transparent; + width: 90%; + border-bottom: 1px solid var(--color-tab-bg); +} + +main .manage-order-table .add-item { + display: inline-block; + text-decoration: none; + color: #676d72; + padding: 25px 0; +} + +main .manage-order-table .add-item i { + padding-right: 5px; +} + +main .manage-order-table .add-item:hover { + color: #4f5357; +} + +main .manage-order-table .delete-item { + cursor: pointer; + color: #676d72; +} + +main .manage-order-table .delete-item:hover { + color: #b44a4a; +} + +.table { + overflow-x: auto; + padding: 0 10px; +} + +.table table { + width: 100%; + border-collapse: collapse; +} + +.table table thead td { + font-weight: 600; + font-size: 14px; + padding: 15px 0; +} + +.table table thead td a { + font-weight: inherit; + font-size: inherit; + color: inherit; + text-decoration: none; +} + +.table table thead td i { + padding-left: 5px; +} + +.table table thead tr { + border-bottom: 1px solid #f0f1f2; +} + +.table table tbody tr:first-child td { + padding-top: 10px; +} + +.table table tbody td { + padding: 5px; +} + +.table table tbody .img { + padding: 1px 0; +} + +.table table tbody .rrp { + color: var(--color-danger); +} + +.table table tbody .status { + padding: 4px 7px; + border-radius: 4px; + background-color: var(--color-status-neutral); + font-weight: 500; + font-size: 12px; + color: var(--color-bg-body); +} + +.table table tbody .status.enabled { + padding: 4px 7px; + border-radius: 4px; + background-color: var(--color-status-enabled); + font-weight: 500; + font-size: 12px; + color: var(--color-bg-body); +} + +.table table tbody .status.disabled { + padding: 4px 7px; + border-radius: 4px; + background-color: var(--color-status-disabled); + font-weight: 500; + font-size: 12px; + color: var(--color-bg-body); +} + + +.status { + padding: 4px 7px; + border-radius: 4px; + background-color: var(--color-status-neutral); + font-weight: 500; + font-size: 12px; + color: var(--color-bg-body); +} + +.status.enabled { + background-color: var(--color-status-enabled); +} + +.status.disabled { + background-color: var(--color-status-disabled); +} + +.status.id4 { + background-color: var(--color-status-enabled); +} + +.status.id3 { +background-color: var(--color-status-enabled); +} + +.status.id2 { + background-color: var(--color-status-warning); +} +.table table tbody .status.service_renewal{ + background-color: var(--color-status-warning); +} + +.table table tbody .status.firmware_update{ + background-color: var(--color-status-warning); +} + +.table table tbody .status.warranty_outdated{ + background-color: var(--color-status-warning); +} +.table table tbody .status.warranty { + background-color: var(--color-status-enabled); +} + +.table table tbody .status.service{ + background-color: var(--color-status-enabled); +} + +.table table tbody .status.firmware_recent{ + background-color: var(--color-status-enabled); +} + +.status.id5 { + background-color: var(--color-status-disabled); +} + +.table table tbody .status.id4, .table table tbody .status.id3, .table table tbody .status.warranty { + background-color: var(--color-status-enabled); +} + +.table table tbody .status.id2 { + background-color: var(--color-status-warning); +} + +.table table tbody .status.id5{ + background-color: var(--color-status-disabled); +} + +.product-media-tab, .product-options-tab, .product-downloads-tab { + max-width: 800px; +} + +.product-media-tab .product-media, .product-media-tab .product-option, .product-media-tab .product-download, .product-options-tab .product-media, .product-options-tab .product-option, .product-options-tab .product-download, .product-downloads-tab .product-media, .product-downloads-tab .product-option, .product-downloads-tab .product-download { + display: flex; + border-right: 4px solid #e8ebee; + margin-bottom: 15px; +} + +.product-media-tab .product-media:first-child, .product-media-tab .product-option:first-child, .product-media-tab .product-download:first-child, .product-options-tab .product-media:first-child, .product-options-tab .product-option:first-child, .product-options-tab .product-download:first-child, .product-downloads-tab .product-media:first-child, .product-downloads-tab .product-option:first-child, .product-downloads-tab .product-download:first-child { + border-right: 4px solid #72a0d4; +} + +.product-media-tab .product-media:first-child .move-up, .product-media-tab .product-option:first-child .move-up, .product-media-tab .product-download:first-child .move-up, .product-options-tab .product-media:first-child .move-up, .product-options-tab .product-option:first-child .move-up, .product-options-tab .product-download:first-child .move-up, .product-downloads-tab .product-media:first-child .move-up, .product-downloads-tab .product-option:first-child .move-up, .product-downloads-tab .product-download:first-child .move-up { + display: none; +} + +.product-media-tab .product-media:last-child .move-down, .product-media-tab .product-option:last-child .move-down, .product-media-tab .product-download:last-child .move-down, .product-options-tab .product-media:last-child .move-down, .product-options-tab .product-option:last-child .move-down, .product-options-tab .product-download:last-child .move-down, .product-downloads-tab .product-media:last-child .move-down, .product-downloads-tab .product-option:last-child .move-down, .product-downloads-tab .product-download:last-child .move-down { + display: none; +} + +.product-media-tab .product-media .media-index, .product-media-tab .product-media .option-index, .product-media-tab .product-media .download-index, .product-media-tab .product-option .media-index, .product-media-tab .product-option .option-index, .product-media-tab .product-option .download-index, .product-media-tab .product-download .media-index, .product-media-tab .product-download .option-index, .product-media-tab .product-download .download-index, .product-options-tab .product-media .media-index, .product-options-tab .product-media .option-index, .product-options-tab .product-media .download-index, .product-options-tab .product-option .media-index, .product-options-tab .product-option .option-index, .product-options-tab .product-option .download-index, .product-options-tab .product-download .media-index, .product-options-tab .product-download .option-index, .product-options-tab .product-download .download-index, .product-downloads-tab .product-media .media-index, .product-downloads-tab .product-media .option-index, .product-downloads-tab .product-media .download-index, .product-downloads-tab .product-option .media-index, .product-downloads-tab .product-option .option-index, .product-downloads-tab .product-option .download-index, .product-downloads-tab .product-download .media-index, .product-downloads-tab .product-download .option-index, .product-downloads-tab .product-download .download-index { + display: flex; + color: #bcc0c4; + font-weight: 500; + align-items: center; + padding-right: 15px; + font-weight: 14px; + width: 30px; +} + +.product-media-tab .product-media .media-img, .product-media-tab .product-option .media-img, .product-media-tab .product-download .media-img, .product-options-tab .product-media .media-img, .product-options-tab .product-option .media-img, .product-options-tab .product-download .media-img, .product-downloads-tab .product-media .media-img, .product-downloads-tab .product-option .media-img, .product-downloads-tab .product-download .media-img { + text-decoration: none; + display: flex; + height: 70px; + width: 100px; + border: 1px solid #ddd; + padding: 5px; +} + +.product-media-tab .product-media .media-img img, .product-media-tab .product-option .media-img img, .product-media-tab .product-download .media-img img, .product-options-tab .product-media .media-img img, .product-options-tab .product-option .media-img img, .product-options-tab .product-download .media-img img, .product-downloads-tab .product-media .media-img img, .product-downloads-tab .product-option .media-img img, .product-downloads-tab .product-download .media-img img { + width: 100%; + height: 100%; + object-fit: contain; +} + +.product-media-tab .product-media .media-text, .product-media-tab .product-media .option-text, .product-media-tab .product-media .download-text, .product-media-tab .product-option .media-text, .product-media-tab .product-option .option-text, .product-media-tab .product-option .download-text, .product-media-tab .product-download .media-text, .product-media-tab .product-download .option-text, .product-media-tab .product-download .download-text, .product-options-tab .product-media .media-text, .product-options-tab .product-media .option-text, .product-options-tab .product-media .download-text, .product-options-tab .product-option .media-text, .product-options-tab .product-option .option-text, .product-options-tab .product-option .download-text, .product-options-tab .product-download .media-text, .product-options-tab .product-download .option-text, .product-options-tab .product-download .download-text, .product-downloads-tab .product-media .media-text, .product-downloads-tab .product-media .option-text, .product-downloads-tab .product-media .download-text, .product-downloads-tab .product-option .media-text, .product-downloads-tab .product-option .option-text, .product-downloads-tab .product-option .download-text, .product-downloads-tab .product-download .media-text, .product-downloads-tab .product-download .option-text, .product-downloads-tab .product-download .download-text { + display: flex; + flex-flow: column; + justify-content: center; + flex: 1; + padding-left: 15px; +} + +.product-media-tab .product-media .media-text h3, .product-media-tab .product-media .option-text h3, .product-media-tab .product-media .download-text h3, .product-media-tab .product-option .media-text h3, .product-media-tab .product-option .option-text h3, .product-media-tab .product-option .download-text h3, .product-media-tab .product-download .media-text h3, .product-media-tab .product-download .option-text h3, .product-media-tab .product-download .download-text h3, .product-options-tab .product-media .media-text h3, .product-options-tab .product-media .option-text h3, .product-options-tab .product-media .download-text h3, .product-options-tab .product-option .media-text h3, .product-options-tab .product-option .option-text h3, .product-options-tab .product-option .download-text h3, .product-options-tab .product-download .media-text h3, .product-options-tab .product-download .option-text h3, .product-options-tab .product-download .download-text h3, .product-downloads-tab .product-media .media-text h3, .product-downloads-tab .product-media .option-text h3, .product-downloads-tab .product-media .download-text h3, .product-downloads-tab .product-option .media-text h3, .product-downloads-tab .product-option .option-text h3, .product-downloads-tab .product-option .download-text h3, .product-downloads-tab .product-download .media-text h3, .product-downloads-tab .product-download .option-text h3, .product-downloads-tab .product-download .download-text h3 { + font-weight: 500; +} + +.product-media-tab .product-media .media-text p, .product-media-tab .product-media .option-text p, .product-media-tab .product-media .download-text p, .product-media-tab .product-option .media-text p, .product-media-tab .product-option .option-text p, .product-media-tab .product-option .download-text p, .product-media-tab .product-download .media-text p, .product-media-tab .product-download .option-text p, .product-media-tab .product-download .download-text p, .product-options-tab .product-media .media-text p, .product-options-tab .product-media .option-text p, .product-options-tab .product-media .download-text p, .product-options-tab .product-option .media-text p, .product-options-tab .product-option .option-text p, .product-options-tab .product-option .download-text p, .product-options-tab .product-download .media-text p, .product-options-tab .product-download .option-text p, .product-options-tab .product-download .download-text p, .product-downloads-tab .product-media .media-text p, .product-downloads-tab .product-media .option-text p, .product-downloads-tab .product-media .download-text p, .product-downloads-tab .product-option .media-text p, .product-downloads-tab .product-option .option-text p, .product-downloads-tab .product-option .download-text p, .product-downloads-tab .product-download .media-text p, .product-downloads-tab .product-download .option-text p, .product-downloads-tab .product-download .download-text p { + margin: 0; + color: var(--color-muted); + font-size: 14px; +} + +.product-media-tab .product-media .media-position, .product-media-tab .product-media .option-position, .product-media-tab .product-media .download-position, .product-media-tab .product-option .media-position, .product-media-tab .product-option .option-position, .product-media-tab .product-option .download-position, .product-media-tab .product-download .media-position, .product-media-tab .product-download .option-position, .product-media-tab .product-download .download-position, .product-options-tab .product-media .media-position, .product-options-tab .product-media .option-position, .product-options-tab .product-media .download-position, .product-options-tab .product-option .media-position, .product-options-tab .product-option .option-position, .product-options-tab .product-option .download-position, .product-options-tab .product-download .media-position, .product-options-tab .product-download .option-position, .product-options-tab .product-download .download-position, .product-downloads-tab .product-media .media-position, .product-downloads-tab .product-media .option-position, .product-downloads-tab .product-media .download-position, .product-downloads-tab .product-option .media-position, .product-downloads-tab .product-option .option-position, .product-downloads-tab .product-option .download-position, .product-downloads-tab .product-download .media-position, .product-downloads-tab .product-download .option-position, .product-downloads-tab .product-download .download-position { + display: flex; + width: 100px; + justify-content: flex-end; + align-items: center; + padding-right: 20px; +} + +.product-media-tab .product-media .media-position i, .product-media-tab .product-media .option-position i, .product-media-tab .product-media .download-position i, .product-media-tab .product-option .media-position i, .product-media-tab .product-option .option-position i, .product-media-tab .product-option .download-position i, .product-media-tab .product-download .media-position i, .product-media-tab .product-download .option-position i, .product-media-tab .product-download .download-position i, .product-options-tab .product-media .media-position i, .product-options-tab .product-media .option-position i, .product-options-tab .product-media .download-position i, .product-options-tab .product-option .media-position i, .product-options-tab .product-option .option-position i, .product-options-tab .product-option .download-position i, .product-options-tab .product-download .media-position i, .product-options-tab .product-download .option-position i, .product-options-tab .product-download .download-position i, .product-downloads-tab .product-media .media-position i, .product-downloads-tab .product-media .option-position i, .product-downloads-tab .product-media .download-position i, .product-downloads-tab .product-option .media-position i, .product-downloads-tab .product-option .option-position i, .product-downloads-tab .product-option .download-position i, .product-downloads-tab .product-download .media-position i, .product-downloads-tab .product-download .option-position i, .product-downloads-tab .product-download .download-position i { + cursor: pointer; + font-size: 20px; + padding-left: 15px; + color: #cbcfd4; +} + +.product-media-tab .product-media .media-position i:hover, .product-media-tab .product-media .option-position i:hover, .product-media-tab .product-media .download-position i:hover, .product-media-tab .product-option .media-position i:hover, .product-media-tab .product-option .option-position i:hover, .product-media-tab .product-option .download-position i:hover, .product-media-tab .product-download .media-position i:hover, .product-media-tab .product-download .option-position i:hover, .product-media-tab .product-download .download-position i:hover, .product-options-tab .product-media .media-position i:hover, .product-options-tab .product-media .option-position i:hover, .product-options-tab .product-media .download-position i:hover, .product-options-tab .product-option .media-position i:hover, .product-options-tab .product-option .option-position i:hover, .product-options-tab .product-option .download-position i:hover, .product-options-tab .product-download .media-position i:hover, .product-options-tab .product-download .option-position i:hover, .product-options-tab .product-download .download-position i:hover, .product-downloads-tab .product-media .media-position i:hover, .product-downloads-tab .product-media .option-position i:hover, .product-downloads-tab .product-media .download-position i:hover, .product-downloads-tab .product-option .media-position i:hover, .product-downloads-tab .product-option .option-position i:hover, .product-downloads-tab .product-option .download-position i:hover, .product-downloads-tab .product-download .media-position i:hover, .product-downloads-tab .product-download .option-position i:hover, .product-downloads-tab .product-download .download-position i:hover { + color: #afb5bd; +} + +.product-media-tab .product-media .media-position i.media-delete, .product-media-tab .product-media .media-position i.option-delete, .product-media-tab .product-media .media-position i.download-delete, .product-media-tab .product-media .option-position i.media-delete, .product-media-tab .product-media .option-position i.option-delete, .product-media-tab .product-media .option-position i.download-delete, .product-media-tab .product-media .download-position i.media-delete, .product-media-tab .product-media .download-position i.option-delete, .product-media-tab .product-media .download-position i.download-delete, .product-media-tab .product-option .media-position i.media-delete, .product-media-tab .product-option .media-position i.option-delete, .product-media-tab .product-option .media-position i.download-delete, .product-media-tab .product-option .option-position i.media-delete, .product-media-tab .product-option .option-position i.option-delete, .product-media-tab .product-option .option-position i.download-delete, .product-media-tab .product-option .download-position i.media-delete, .product-media-tab .product-option .download-position i.option-delete, .product-media-tab .product-option .download-position i.download-delete, .product-media-tab .product-download .media-position i.media-delete, .product-media-tab .product-download .media-position i.option-delete, .product-media-tab .product-download .media-position i.download-delete, .product-media-tab .product-download .option-position i.media-delete, .product-media-tab .product-download .option-position i.option-delete, .product-media-tab .product-download .option-position i.download-delete, .product-media-tab .product-download .download-position i.media-delete, .product-media-tab .product-download .download-position i.option-delete, .product-media-tab .product-download .download-position i.download-delete, .product-options-tab .product-media .media-position i.media-delete, .product-options-tab .product-media .media-position i.option-delete, .product-options-tab .product-media .media-position i.download-delete, .product-options-tab .product-media .option-position i.media-delete, .product-options-tab .product-media .option-position i.option-delete, .product-options-tab .product-media .option-position i.download-delete, .product-options-tab .product-media .download-position i.media-delete, .product-options-tab .product-media .download-position i.option-delete, .product-options-tab .product-media .download-position i.download-delete, .product-options-tab .product-option .media-position i.media-delete, .product-options-tab .product-option .media-position i.option-delete, .product-options-tab .product-option .media-position i.download-delete, .product-options-tab .product-option .option-position i.media-delete, .product-options-tab .product-option .option-position i.option-delete, .product-options-tab .product-option .option-position i.download-delete, .product-options-tab .product-option .download-position i.media-delete, .product-options-tab .product-option .download-position i.option-delete, .product-options-tab .product-option .download-position i.download-delete, .product-options-tab .product-download .media-position i.media-delete, .product-options-tab .product-download .media-position i.option-delete, .product-options-tab .product-download .media-position i.download-delete, .product-options-tab .product-download .option-position i.media-delete, .product-options-tab .product-download .option-position i.option-delete, .product-options-tab .product-download .option-position i.download-delete, .product-options-tab .product-download .download-position i.media-delete, .product-options-tab .product-download .download-position i.option-delete, .product-options-tab .product-download .download-position i.download-delete, .product-downloads-tab .product-media .media-position i.media-delete, .product-downloads-tab .product-media .media-position i.option-delete, .product-downloads-tab .product-media .media-position i.download-delete, .product-downloads-tab .product-media .option-position i.media-delete, .product-downloads-tab .product-media .option-position i.option-delete, .product-downloads-tab .product-media .option-position i.download-delete, .product-downloads-tab .product-media .download-position i.media-delete, .product-downloads-tab .product-media .download-position i.option-delete, .product-downloads-tab .product-media .download-position i.download-delete, .product-downloads-tab .product-option .media-position i.media-delete, .product-downloads-tab .product-option .media-position i.option-delete, .product-downloads-tab .product-option .media-position i.download-delete, .product-downloads-tab .product-option .option-position i.media-delete, .product-downloads-tab .product-option .option-position i.option-delete, .product-downloads-tab .product-option .option-position i.download-delete, .product-downloads-tab .product-option .download-position i.media-delete, .product-downloads-tab .product-option .download-position i.option-delete, .product-downloads-tab .product-option .download-position i.download-delete, .product-downloads-tab .product-download .media-position i.media-delete, .product-downloads-tab .product-download .media-position i.option-delete, .product-downloads-tab .product-download .media-position i.download-delete, .product-downloads-tab .product-download .option-position i.media-delete, .product-downloads-tab .product-download .option-position i.option-delete, .product-downloads-tab .product-download .option-position i.download-delete, .product-downloads-tab .product-download .download-position i.media-delete, .product-downloads-tab .product-download .download-position i.option-delete, .product-downloads-tab .product-download .download-position i.download-delete { + padding-right: 5px; + color: #e1e4e6; +} + +.product-media-tab .product-media .media-position i.media-delete:hover, .product-media-tab .product-media .media-position i.option-delete:hover, .product-media-tab .product-media .media-position i.download-delete:hover, .product-media-tab .product-media .option-position i.media-delete:hover, .product-media-tab .product-media .option-position i.option-delete:hover, .product-media-tab .product-media .option-position i.download-delete:hover, .product-media-tab .product-media .download-position i.media-delete:hover, .product-media-tab .product-media .download-position i.option-delete:hover, .product-media-tab .product-media .download-position i.download-delete:hover, .product-media-tab .product-option .media-position i.media-delete:hover, .product-media-tab .product-option .media-position i.option-delete:hover, .product-media-tab .product-option .media-position i.download-delete:hover, .product-media-tab .product-option .option-position i.media-delete:hover, .product-media-tab .product-option .option-position i.option-delete:hover, .product-media-tab .product-option .option-position i.download-delete:hover, .product-media-tab .product-option .download-position i.media-delete:hover, .product-media-tab .product-option .download-position i.option-delete:hover, .product-media-tab .product-option .download-position i.download-delete:hover, .product-media-tab .product-download .media-position i.media-delete:hover, .product-media-tab .product-download .media-position i.option-delete:hover, .product-media-tab .product-download .media-position i.download-delete:hover, .product-media-tab .product-download .option-position i.media-delete:hover, .product-media-tab .product-download .option-position i.option-delete:hover, .product-media-tab .product-download .option-position i.download-delete:hover, .product-media-tab .product-download .download-position i.media-delete:hover, .product-media-tab .product-download .download-position i.option-delete:hover, .product-media-tab .product-download .download-position i.download-delete:hover, .product-options-tab .product-media .media-position i.media-delete:hover, .product-options-tab .product-media .media-position i.option-delete:hover, .product-options-tab .product-media .media-position i.download-delete:hover, .product-options-tab .product-media .option-position i.media-delete:hover, .product-options-tab .product-media .option-position i.option-delete:hover, .product-options-tab .product-media .option-position i.download-delete:hover, .product-options-tab .product-media .download-position i.media-delete:hover, .product-options-tab .product-media .download-position i.option-delete:hover, .product-options-tab .product-media .download-position i.download-delete:hover, .product-options-tab .product-option .media-position i.media-delete:hover, .product-options-tab .product-option .media-position i.option-delete:hover, .product-options-tab .product-option .media-position i.download-delete:hover, .product-options-tab .product-option .option-position i.media-delete:hover, .product-options-tab .product-option .option-position i.option-delete:hover, .product-options-tab .product-option .option-position i.download-delete:hover, .product-options-tab .product-option .download-position i.media-delete:hover, .product-options-tab .product-option .download-position i.option-delete:hover, .product-options-tab .product-option .download-position i.download-delete:hover, .product-options-tab .product-download .media-position i.media-delete:hover, .product-options-tab .product-download .media-position i.option-delete:hover, .product-options-tab .product-download .media-position i.download-delete:hover, .product-options-tab .product-download .option-position i.media-delete:hover, .product-options-tab .product-download .option-position i.option-delete:hover, .product-options-tab .product-download .option-position i.download-delete:hover, .product-options-tab .product-download .download-position i.media-delete:hover, .product-options-tab .product-download .download-position i.option-delete:hover, .product-options-tab .product-download .download-position i.download-delete:hover, .product-downloads-tab .product-media .media-position i.media-delete:hover, .product-downloads-tab .product-media .media-position i.option-delete:hover, .product-downloads-tab .product-media .media-position i.download-delete:hover, .product-downloads-tab .product-media .option-position i.media-delete:hover, .product-downloads-tab .product-media .option-position i.option-delete:hover, .product-downloads-tab .product-media .option-position i.download-delete:hover, .product-downloads-tab .product-media .download-position i.media-delete:hover, .product-downloads-tab .product-media .download-position i.option-delete:hover, .product-downloads-tab .product-media .download-position i.download-delete:hover, .product-downloads-tab .product-option .media-position i.media-delete:hover, .product-downloads-tab .product-option .media-position i.option-delete:hover, .product-downloads-tab .product-option .media-position i.download-delete:hover, .product-downloads-tab .product-option .option-position i.media-delete:hover, .product-downloads-tab .product-option .option-position i.option-delete:hover, .product-downloads-tab .product-option .option-position i.download-delete:hover, .product-downloads-tab .product-option .download-position i.media-delete:hover, .product-downloads-tab .product-option .download-position i.option-delete:hover, .product-downloads-tab .product-option .download-position i.download-delete:hover, .product-downloads-tab .product-download .media-position i.media-delete:hover, .product-downloads-tab .product-download .media-position i.option-delete:hover, .product-downloads-tab .product-download .media-position i.download-delete:hover, .product-downloads-tab .product-download .option-position i.media-delete:hover, .product-downloads-tab .product-download .option-position i.option-delete:hover, .product-downloads-tab .product-download .option-position i.download-delete:hover, .product-downloads-tab .product-download .download-position i.media-delete:hover, .product-downloads-tab .product-download .download-position i.option-delete:hover, .product-downloads-tab .product-download .download-position i.download-delete:hover { + color: #b44a4a; +} + +.product-media-tab .product-media .media-position i.option-edit, .product-media-tab .product-media .option-position i.option-edit, .product-media-tab .product-media .download-position i.option-edit, .product-media-tab .product-option .media-position i.option-edit, .product-media-tab .product-option .option-position i.option-edit, .product-media-tab .product-option .download-position i.option-edit, .product-media-tab .product-download .media-position i.option-edit, .product-media-tab .product-download .option-position i.option-edit, .product-media-tab .product-download .download-position i.option-edit, .product-options-tab .product-media .media-position i.option-edit, .product-options-tab .product-media .option-position i.option-edit, .product-options-tab .product-media .download-position i.option-edit, .product-options-tab .product-option .media-position i.option-edit, .product-options-tab .product-option .option-position i.option-edit, .product-options-tab .product-option .download-position i.option-edit, .product-options-tab .product-download .media-position i.option-edit, .product-options-tab .product-download .option-position i.option-edit, .product-options-tab .product-download .download-position i.option-edit, .product-downloads-tab .product-media .media-position i.option-edit, .product-downloads-tab .product-media .option-position i.option-edit, .product-downloads-tab .product-media .download-position i.option-edit, .product-downloads-tab .product-option .media-position i.option-edit, .product-downloads-tab .product-option .option-position i.option-edit, .product-downloads-tab .product-option .download-position i.option-edit, .product-downloads-tab .product-download .media-position i.option-edit, .product-downloads-tab .product-download .option-position i.option-edit, .product-downloads-tab .product-download .download-position i.option-edit { + font-size: 14px; + padding-right: 5px; + color: #e1e4e6; +} + +.product-media-tab .product-media .media-position i.option-edit:hover, .product-media-tab .product-media .option-position i.option-edit:hover, .product-media-tab .product-media .download-position i.option-edit:hover, .product-media-tab .product-option .media-position i.option-edit:hover, .product-media-tab .product-option .option-position i.option-edit:hover, .product-media-tab .product-option .download-position i.option-edit:hover, .product-media-tab .product-download .media-position i.option-edit:hover, .product-media-tab .product-download .option-position i.option-edit:hover, .product-media-tab .product-download .download-position i.option-edit:hover, .product-options-tab .product-media .media-position i.option-edit:hover, .product-options-tab .product-media .option-position i.option-edit:hover, .product-options-tab .product-media .download-position i.option-edit:hover, .product-options-tab .product-option .media-position i.option-edit:hover, .product-options-tab .product-option .option-position i.option-edit:hover, .product-options-tab .product-option .download-position i.option-edit:hover, .product-options-tab .product-download .media-position i.option-edit:hover, .product-options-tab .product-download .option-position i.option-edit:hover, .product-options-tab .product-download .download-position i.option-edit:hover, .product-downloads-tab .product-media .media-position i.option-edit:hover, .product-downloads-tab .product-media .option-position i.option-edit:hover, .product-downloads-tab .product-media .download-position i.option-edit:hover, .product-downloads-tab .product-option .media-position i.option-edit:hover, .product-downloads-tab .product-option .option-position i.option-edit:hover, .product-downloads-tab .product-option .download-position i.option-edit:hover, .product-downloads-tab .product-download .media-position i.option-edit:hover, .product-downloads-tab .product-download .option-position i.option-edit:hover, .product-downloads-tab .product-download .download-position i.option-edit:hover { + color: #4ab46d; +} + +.link1, .link2 { + text-decoration: none; + color: var(--color-accent-blue); + border-bottom: 1px dotted; + margin: 0 5px 0 0; +} + +.link1:hover, .link2:hover { + color: var(--color-accent-blue-hover); +} + +.link2 { + color: var(--color-accent-red); +} + +.link2:hover { + color: var(--color-accent-red-hover); +} + +.title1 { + color: #6a6e75; + border-bottom: 1px solid #f0f1f2; + margin-bottom: 15px; + padding-bottom: 15px; + font-weight: 500; +} + +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + text-decoration: none; + appearance: none; + cursor: pointer; + border: 0; + background: var(--color-selected-bg); + color: var(--color-bg-body); + padding: 0 14px; + font-size: 14px; + font-weight: 600; + border-radius: 4px; + height: 38px; + margin: 2px; + font-style: italic; +} + +.btn2 { + display: inline-flex; + align-items: center; + justify-content: center; + text-decoration: none; + appearance: none; + cursor: pointer; + border: 0; + background: var(--color-btn-secondary); + color: var(--color-bg-body); + padding: 0px 10px; + font-size: 14px; + font-weight: 600; + border-radius: 4px; + height: 20px; + margin: 2px; + font-style: italic; +} + +a.btn:after{ + content: ' '; + display: inline-block; + border-bottom: 1px solid var(--color-bg-body); + border-right: 1px solid var(--color-bg-body); + height: 8px; + width: 8px; + transform: rotate(-45deg); + margin-left: 1rem; +} + +.btn_link { + display: inline-flex; + align-items: center; + justify-content: center; + text-decoration: none; + appearance: none; + cursor: pointer; + border: 0; + background: var(--color-btn-neutral); + color: #75797e; + padding: 0 14px; + font-size: 12px; + font-weight: 600; + border-radius: 4px; + height: 30px; + margin: 2px; + font-style: italic; +} + +a.btn_link:after{ + content: ' '; + display: inline-block; + border-bottom: 1px solid #75797e; + border-right: 1px solid #75797e; + height: 8px; + width: 8px; + transform: rotate(-45deg); + margin-left: 1rem; +} + +.btn:hover { + background: var(--color-btn-hover-bg); +} + +.btn.green { + background: #4ab46d; +} + +.btn.green:hover { + background: #46a966; +} + +.btn.red { + background: #b44a4a; +} + +.btn.red:hover { + background: #a94646; +} + +.btn.alt { + color: #75797e; + border: 1px solid #d4dbde; + box-shadow: 0px 0px 3px 1px rgba(0, 0, 0, 0.03); + background: var(--color-btn-neutral); +} + +.btn.alt:hover { + background: #eef1f2; +} + +.btn.disabled { + background: var(--color-disabled); +} + +.btn.disabled:hover { + background: var(--color-disabled-hover); +} + +.btn.small { + padding: 8px 12px; + font-size: 12px; +} + +.btn .loader, +.btn .loader::after { + width: 15px; + height: 15px; +} + +.btn .loader { + margin: 0; + border-top: 2px solid rgba(255, 255, 255, 0.4); + border-right: 2px solid rgba(255, 255, 255, 0.4); + border-bottom: 2px solid rgba(255, 255, 255, 0.4); + border-left: 2px solid rgba(255, 255, 255, 0.9); +} + +.dialog { + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + position: fixed; + top: 0; + left: 0; + display: none; + z-index: 999999; + align-items: center; + justify-content: center; +} + +.dialog .content { + transform: scale(0.5); + background-color: var(--color-bg-body); + box-shadow: 0px 0px 5px 2px rgba(0, 0, 0, 0.03); + width: 400px; +} + +.dialog .content .heading { + display: flex; + padding: 20px; + font-weight: 600; + justify-content: space-between; + border-bottom: 1px solid #ebeced; + align-items: center; +} + +.dialog .content .heading span { + font-size: 24px; + line-height: 24px; + padding-bottom: 4px; + cursor: pointer; + color: var(--color-title-muted); +} + +.dialog .content .heading span:hover { + color: var(--color-hover-dark); +} + +.dialog .content .footer { + border-top: 1px solid #ebeced; + background-color: var(--color-hover-light); +} + +.dialog.large .content { + width: 900px; +} + +.dialog.medium .content { + width: 600px; +} + +.dialog.open { + display: flex; +} + +.dialog.open .content { + transform: scale(1); + transition: all 0.2s ease; +} + +.media-library-modal .media { + display: flex; +} + +.media-library-modal .media .list { + display: flex; + flex-flow: wrap; + align-items: flex-start; + align-content: flex-start; + width: 75%; + height: 460px; + overflow-y: auto; + scrollbar-width: thin; + padding: 10px; +} + +.media-library-modal .media .list > a { + position: relative; + display: flex; + height: 100px; + width: 23.4%; + border: 1px solid #ddd; + padding: 5px; + margin: 5px; +} + +.media-library-modal .media .list > a img { + width: 100%; + height: 100%; + object-fit: contain; +} + +.media-library-modal .media .list > a.selected { + border: 2px solid #237fe8; +} + +.media-library-modal .media .list > a.selected::before { + position: absolute; + font-family: 'Font Awesome 5 Free'; + content: '\f00c'; + display: inline-block; + vertical-align: middle; + font-weight: 900; + bottom: 0; + right: 0; + color: var(--color-bg-body); + background-color: #237fe8; + font-size: 12px; + padding: 4px 4px 1px 4px; +} + +.media-library-modal .media .list .list-header { + display: flex; + width: 100%; + justify-content: space-between; + padding: 5px 5px 10px 5px; +} + +.media-library-modal .media .list .list-header input { + border: 0; + padding: 5px 0; + border-bottom: 1px solid var(--color-tab-bg); +} + +.media-library-modal .media .details { + width: 25%; + padding: 15px; + background-color: #f9f9fa; + border-left: 1px solid #ebeced; + height: 460px; + overflow-y: auto; + scrollbar-width: thin; +} + +.media-library-modal .media .details h3 { + margin: 0; + padding: 0; + font-size: 14px; + word-break: break-all; +} + +.media-library-modal .media .details label { + display: block; + margin: 0; + padding: 15px 0 0 0; + font-size: 14px; + font-weight: 500; +} + +.media-library-modal .media .details img { + max-width: 100%; + max-height: 100px; + padding-top: 10px; +} + +.media-library-modal .media .details input { + border: 0; + padding: 5px 0; + background: transparent; + width: 100%; + font-size: 14px; + border-bottom: 1px solid var(--color-tab-bg); +} + +.media-library-modal .media .details .media-links { + padding-top: 15px; +} + +.media-library-modal .media .details .media-links .save-media { + display: none; +} + +.media-library-modal .media .details .media-links a { + font-size: 14px; +} + +.media-library-modal .media .list::-webkit-scrollbar, .media-library-modal .media .details::-webkit-scrollbar { + width: 6px; + background: var(--color-bg-body); +} + +.media-library-modal .media .list::-webkit-scrollbar-thumb, .media-library-modal .media .details::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, 0.1); + border-radius: 50px; +} + +.options-modal .body { + max-height: 400px; + overflow-y: auto; + padding: 20px; +} + +.options-modal .body input[type="text"], .options-modal .body input[type="number"], .options-modal .body input[type="datetime-local"], .options-modal .body select { + border: 0; + padding: 10px 0; + height: 40px; + background: transparent; + width: 100%; + border-bottom: 1px solid var(--color-tab-bg); +} + +.options-modal .body select { + padding: 0; +} + +.options-modal .body .option-header { + display: flex; + width: 70%; +} + +.options-modal .body .option-header input { + margin-right: 10px; +} + +.options-modal .body .option-header label { + display: flex; + justify-content: center; + align-items: center; + padding-left: 10px; +} + +.options-modal .body .option-content { + display: none; + flex-flow: column; +} + +.options-modal .body .table { + width: 100%; + padding: 0; +} + +.options-modal .body .table .input-group { + display: flex; +} + +.options-modal .body .table tbody td input { + font-size: 14px; +} + +.options-modal .body .table tbody td { + padding-right: 10px; +} + +.options-modal .body .table tbody td .modifier { + width: 45px; +} + +.options-modal .body .table tbody td .modifier ~ input { + padding-left: 5px; +} + +.options-modal .body .add-option-value-btn { + text-decoration: none; + font-weight: 400; + color: #676d72; + font-size: 14px; + padding: 15px 0; +} + +.options-modal .body .add-option-value-btn i { + padding-right: 5px; +} + +.options-modal .body .add-option-value-btn:hover { + color: #4f5357; +} + +.options-modal .body .remove-option-value { + cursor: pointer; + color: #676d72; +} + +.options-modal .body .remove-option-value:hover { + color: #b44a4a; +} + +.downloads-modal .body { + padding: 20px; +} + +.downloads-modal .body input { + border: 0; + padding: 10px 0; + height: 40px; + font-size: 14px; + background: transparent; + width: 100%; + border-bottom: 1px solid var(--color-tab-bg); +} + +.downloads-modal .body label { + font-weight: 500; +} + +.edit-media-modal .body { + padding: 20px; +} + +.edit-media-modal .body label { + display: block; + margin: 0; + padding: 15px 0 0 0; + font-size: 14px; + font-weight: 500; +} + +.edit-media-modal .body img { + max-width: 100%; + max-height: 100px; + padding-top: 10px; +} + +.edit-media-modal .body input { + border: 0; + padding: 5px 0; + background: transparent; + width: 100%; + font-size: 14px; + border-bottom: 1px solid var(--color-tab-bg); +} + +.loader, +.loader::after { + border-radius: 50%; + width: 50px; + height: 50px; +} + +.loader { + position: relative; + margin: 60px auto; + border-top: 2px solid rgba(154, 158, 162, 0.2); + border-right: 2px solid rgba(154, 158, 162, 0.2); + border-bottom: 2px solid rgba(154, 158, 162, 0.2); + border-left: 2px solid #9a9ea2; + transform: translateZ(0); + animation: loader 1.1s infinite linear; +} + +@keyframes loader { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} + +.pad-1 { + padding: 5px; +} + +.mar-1 { + margin: 5px; +} + +.pad-2 { + padding: 10px; +} + +.mar-2 { + margin: 10px; +} + +.pad-3 { + padding: 15px; +} + +.mar-3 { + margin: 15px; +} + +.pad-4 { + padding: 20px; +} + +.mar-4 { + margin: 20px; +} + +.pad-5 { + padding: 25px; +} + +.mar-5 { + margin: 25px; +} + +.pad-bot-1 { + padding-bottom: 5px; +} + +.pad-top-1 { + padding-top: 5px; +} + +.pad-left-1 { + padding-left: 5px; +} + +.pad-right-1 { + padding-right: 5px; +} + +.pad-x-1 { + padding-left: 5px; + padding-right: 5px; +} + +.pad-y-1 { + padding-top: 5px; + padding-bottom: 5px; +} + +.mar-bot-1 { + margin-bottom: 5px; +} + +.mar-top-1 { + margin-top: 5px; +} + +.mar-left-1 { + margin-left: 5px; +} + +.mar-right-1 { + margin-right: 5px; +} + +.mar-x-1 { + margin-top: 5px; + margin-bottom: 5px; +} + +.mar-y-1 { + margin-left: 5px; + margin-right: 5px; +} + +.pad-bot-2 { + padding-bottom: 10px; +} + +.pad-top-2 { + padding-top: 10px; +} + +.pad-left-2 { + padding-left: 10px; +} + +.pad-right-2 { + padding-right: 10px; +} + +.pad-x-2 { + padding-left: 10px; + padding-right: 10px; +} + +.pad-y-2 { + padding-top: 10px; + padding-bottom: 10px; +} + +.mar-bot-2 { + margin-bottom: 10px; +} + +.mar-top-2 { + margin-top: 10px; +} + +.mar-left-2 { + margin-left: 10px; +} + +.mar-right-2 { + margin-right: 10px; +} + +.mar-x-2 { + margin-top: 10px; + margin-bottom: 10px; +} + +.mar-y-2 { + margin-left: 10px; + margin-right: 10px; +} + +.pad-bot-3 { + padding-bottom: 15px; +} + +.pad-top-3 { + padding-top: 15px; +} + +.pad-left-3 { + padding-left: 15px; +} + +.pad-right-3 { + padding-right: 15px; +} + +.pad-x-3 { + padding-left: 15px; + padding-right: 15px; +} + +.pad-y-3 { + padding-top: 15px; + padding-bottom: 15px; +} + +.mar-bot-3 { + margin-bottom: 15px; +} + +.mar-top-3 { + margin-top: 15px; +} + +.mar-left-3 { + margin-left: 15px; +} + +.mar-right-3 { + margin-right: 15px; +} + +.mar-x-3 { + margin-top: 15px; + margin-bottom: 15px; +} + +.mar-y-3 { + margin-left: 15px; + margin-right: 15px; +} + +.pad-bot-4 { + padding-bottom: 20px; +} + +.pad-top-4 { + padding-top: 20px; +} + +.pad-left-4 { + padding-left: 20px; +} + +.pad-right-4 { + padding-right: 20px; +} + +.pad-x-4 { + padding-left: 20px; + padding-right: 20px; +} + +.pad-y-4 { + padding-top: 20px; + padding-bottom: 20px; +} + +.mar-bot-4 { + margin-bottom: 20px; +} + +.mar-top-4 { + margin-top: 20px; +} + +.mar-left-4 { + margin-left: 20px; +} + +.mar-right-4 { + margin-right: 20px; +} + +.mar-x-4 { + margin-top: 20px; + margin-bottom: 20px; +} + +.mar-y-4 { + margin-left: 20px; + margin-right: 20px; +} + +.pad-bot-5 { + padding-bottom: 25px; +} + +.pad-top-5 { + padding-top: 25px; +} + +.pad-left-5 { + padding-left: 25px; +} + +.pad-right-5 { + padding-right: 25px; +} + +.pad-x-5 { + padding-left: 25px; + padding-right: 25px; +} + +.pad-y-5 { + padding-top: 25px; + padding-bottom: 25px; +} + +.mar-bot-5 { + margin-bottom: 25px; +} + +.mar-top-5 { + margin-top: 25px; +} + +.mar-left-5 { + margin-left: 25px; +} + +.mar-right-5 { + margin-right: 25px; +} + +.mar-x-5 { + margin-top: 25px; + margin-bottom: 25px; +} + +.mar-y-5 { + margin-left: 25px; + margin-right: 25px; +} + +@media screen and (max-width: 1000px) { + header { + padding-left: 0; + } + .responsive-hidden { + display: none !important; + } + .responsive-width-100 { + width: 100% !important; + flex: auto !important; + flex-basis: 100% !important; + } + .responsive-flex-column { + flex-flow: column; + } + .responsive-flex-wrap { + flex-flow: wrap; + } + .responsive-flex { + display: flex; + } + main { + padding: 70px 7px 20px 7px; + } + main .content-header { + max-width: 100%; + } + main .content-header form { + padding-top: 10px; + } + main .content-header form .search input, main .content-header form > select { + padding-right: 0; + margin-left: 0; + } + main .content-block { + padding: 5px; + } + main .content-block .block-header { + padding-top: 10px; + } + main .dashboard { + flex-flow: column; + } + main .dashboard .stat { + width: 100%; + } + .responsive-pad-1 { + padding: 5px; + } + .responsive-mar-1 { + margin: 5px; + } + .responsive-pad-2 { + padding: 10px; + } + .responsive-mar-2 { + margin: 10px; + } + .responsive-pad-3 { + padding: 15px; + } + .responsive-mar-3 { + margin: 15px; + } + .responsive-pad-4 { + padding: 20px; + } + .responsive-mar-4 { + margin: 20px; + } + .responsive-pad-5 { + padding: 25px; + } + .responsive-mar-5 { + margin: 25px; + } + .responsive-pad-bot-1 { + padding-bottom: 5px; + } + .responsive-pad-top-1 { + padding-top: 5px; + } + .responsive-pad-left-1 { + padding-left: 5px; + } + .responsive-pad-right-1 { + padding-right: 5px; + } + .responsive-pad-x-1 { + padding-left: 5px; + padding-right: 5px; + } + .responsive-pad-y-1 { + padding-top: 5px; + padding-bottom: 5px; + } + .responsive-mar-bot-1 { + margin-bottom: 5px; + } + .responsive-mar-top-1 { + margin-top: 5px; + } + .responsive-mar-left-1 { + margin-left: 5px; + } + .responsive-mar-right-1 { + margin-right: 5px; + } + .responsive-mar-x-1 { + margin-top: 5px; + margin-bottom: 5px; + } + .responsive-mar-y-1 { + margin-left: 5px; + margin-right: 5px; + } + .responsive-pad-bot-2 { + padding-bottom: 10px; + } + .responsive-pad-top-2 { + padding-top: 10px; + } + .responsive-pad-left-2 { + padding-left: 10px; + } + .responsive-pad-right-2 { + padding-right: 10px; + } + .responsive-pad-x-2 { + padding-left: 10px; + padding-right: 10px; + } + .responsive-pad-y-2 { + padding-top: 10px; + padding-bottom: 10px; + } + .responsive-mar-bot-2 { + margin-bottom: 10px; + } + .responsive-mar-top-2 { + margin-top: 10px; + } + .responsive-mar-left-2 { + margin-left: 10px; + } + .responsive-mar-right-2 { + margin-right: 10px; + } + .responsive-mar-x-2 { + margin-top: 10px; + margin-bottom: 10px; + } + .responsive-mar-y-2 { + margin-left: 10px; + margin-right: 10px; + } + .responsive-pad-bot-3 { + padding-bottom: 15px; + } + .responsive-pad-top-3 { + padding-top: 15px; + } + .responsive-pad-left-3 { + padding-left: 15px; + } + .responsive-pad-right-3 { + padding-right: 15px; + } + .responsive-pad-x-3 { + padding-left: 15px; + padding-right: 15px; + } + .responsive-pad-y-3 { + padding-top: 15px; + padding-bottom: 15px; + } + .responsive-mar-bot-3 { + margin-bottom: 15px; + } + .responsive-mar-top-3 { + margin-top: 15px; + } + .responsive-mar-left-3 { + margin-left: 15px; + } + .responsive-mar-right-3 { + margin-right: 15px; + } + .responsive-mar-x-3 { + margin-top: 15px; + margin-bottom: 15px; + } + .responsive-mar-y-3 { + margin-left: 15px; + margin-right: 15px; + } + .responsive-pad-bot-4 { + padding-bottom: 20px; + } + .responsive-pad-top-4 { + padding-top: 20px; + } + .responsive-pad-left-4 { + padding-left: 20px; + } + .responsive-pad-right-4 { + padding-right: 20px; + } + .responsive-pad-x-4 { + padding-left: 20px; + padding-right: 20px; + } + .responsive-pad-y-4 { + padding-top: 20px; + padding-bottom: 20px; + } + .responsive-mar-bot-4 { + margin-bottom: 20px; + } + .responsive-mar-top-4 { + margin-top: 20px; + } + .responsive-mar-left-4 { + margin-left: 20px; + } + .responsive-mar-right-4 { + margin-right: 20px; + } + .responsive-mar-x-4 { + margin-top: 20px; + margin-bottom: 20px; + } + .responsive-mar-y-4 { + margin-left: 20px; + margin-right: 20px; + } + .responsive-pad-bot-5 { + padding-bottom: 25px; + } + .responsive-pad-top-5 { + padding-top: 25px; + } + .responsive-pad-left-5 { + padding-left: 25px; + } + .responsive-pad-right-5 { + padding-right: 25px; + } + .responsive-pad-x-5 { + padding-left: 25px; + padding-right: 25px; + } + .responsive-pad-y-5 { + padding-top: 25px; + padding-bottom: 25px; + } + .responsive-mar-bot-5 { + margin-bottom: 25px; + } + .responsive-mar-top-5 { + margin-top: 25px; + } + .responsive-mar-left-5 { + margin-left: 25px; + } + .responsive-mar-right-5 { + margin-right: 25px; + } + .responsive-mar-x-5 { + margin-top: 25px; + margin-bottom: 25px; + } + .responsive-mar-y-5 { + margin-left: 25px; + margin-right: 25px; + } + .media-library-modal { + padding: 10px; + } + .media-library-modal .media { + flex-flow: column; + } + .media-library-modal .media .list { + width: 100%; + height: 220px; + } + .media-library-modal .media .list > a { + width: 29%; + } + .media-library-modal .media .list .list-header input { + max-width: 150px; + width: auto; + } + .media-library-modal .media .details { + width: 100%; + height: 110px; + } + .options-modal { + padding: 10px; + } + .options-modal .body { + max-height: 260px; + } + .options-modal .body .option-header { + width: 100%; + } + .options-modal .body .table thead td { + font-size: 12px; + } + .options-modal .body .table tbody td input { + font-size: 12px; + } + .options-modal .body .table tbody td { + padding-right: 5px; + } + .options-modal .body .table tbody td .modifier { + width: 45px; + } + .options-modal .body .table tbody td .modifier ~ input { + padding-left: 0; + } + .downloads-modal { + padding: 10px; + } + .content-block-wrapper { + flex-flow: column; + } + .content-block-wrapper .content-block { + margin: 15px 0 0 0 !important; + } +} + +#tableView thead { + background-color: #ffd717; + color: var(--color-selected-bg); +} + +#tableView thead td { + font-weight: bold; +} + +#tableView { + border-collapse: collapse; + width: 100%; + border-radius: 5px; + border-style: hidden; + margin: auto; + margin-top: 10px; + background-color: var(--color-bg-body); +} + +#content { + margin-top:20px; + width: 90%; + margin: auto; +} + +.datalist { + width: 100%; + padding: 15px 5px; + margin-bottom: 25px; + border: 0; + border-bottom: 1px solid var(--color-tab-bg); +} + +#readBar { + width:1%; + height: 100%; + background-color: #04aa6d; + text-align: center; + color: white; + border-radius: 5px; + padding: 5px; +} + +input[type='file'] { + display: inline-block; + width: 100%; + padding: 120px 0 0 0; + height: 100px; + overflow: hidden; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + background: url('https://cdn1.iconfinder.com/data/icons/hawcons/32/698394-icon-130-cloud-upload-512.png') center center no-repeat #e4e4e4; + border-radius: 20px; + background-size: 60px 60px; +} + +.dot { + height: 15px; + width: 15px; + font-size: 10px; + color: var(--color-border-light); + display: table-cell; + text-align: center; + vertical-align: middle; + border-radius: 50%; + background-color: #bbb; + } + + .content-wrapper { + width: 1050px; + margin: 0 auto; + } + + .content-wrapper.error { + padding: 40px 0; + } + + .recentlyadded .products, main .products .products-wrapper { + display: flex; + flex-direction: row; + flex-wrap: wrap; + align-items: center; + padding: 40px 0 0 0; + } + + .recentlyadded .products .product, main .products .products-wrapper .product { + display: block; + overflow: hidden; + text-decoration: none; + padding-bottom: 20px; + margin-left: 10px; + text-align: center; + } + .recentlyadded .products .product img, main .products .products-wrapper .product img { + transform: scale(1); + transition: transform 1s; + mix-blend-mode: multiply; + } + + .recentlyadded .products .product .name, main .products .products-wrapper .product .name { + display: block; + color: var(--color-text-default); + font-size: 12px; + text-align: center; + } + + main > .products .products-header { + display: flex; + justify-content: space-between; + align-items: center; + padding-bottom: 40px; + font-size: 10px; + } + + main > .products .products-header label { + padding-left: 20px; + font-size: 10px; + } + + main > .products .products-header select { + padding: 5px; + margin-left: 15px; + border: 1px solid #d5d5d5; + color: var(--color-text-default); + border-radius: 4px; + font-size: 10px; + } + + .product_category_nav { + display: inline-block; + } + + .product_category_nav a { + white-space: nowrap; + text-decoration: none; + color: var(--color-bg-body); + padding: 5px 5px; + margin: 5px; + border: 1px solid var(--color-text-default); + border-radius: 5px; + display: block; + float: left; + background:var(--color-btn-bg); + } + + /* Responsive CSS below */ + @media screen and (max-width: 1050px) { + .content-wrapper { + width: 100%; + margin: 0 auto; + } + + .recentlyadded .products, main .products .products-wrapper { + justify-content: center; + } + .recentlyadded .products .product, main .products .products-wrapper .product { + width: auto; + } + .products .products-header { + flex-flow: column; + } + .products .products-header p { + padding-bottom: 10px; + } + } + + th a { + text-decoration: none; + color: var(--color-text-default); + text-transform: capitalize; +} + +.chart { + display:table; + table-layout: fixed; + width:60%; + max-width:500px; +} + +.chart li{ + position:relative; + display:table-cell; + vertical-align:bottom; + height:100px; + color: var(--color-selected-bg); +} + +.chart span{ + margin:0 1em; + display: block; + background-color: var(--color-selected-bg); + animation: draw 1s ease-in-out; + border-radius: 3px; +} + +.chart span::before{ + position:absolute; + left:0;right:0;top:100%; + padding:5px; + display:block; + color: var(--color-selected-bg); + text-align:center; + content:attr(title); + word-wrap: break-word; + font-size: 10px; +} + +.servicereport { + border-collapse: collapse; + width: 100%; + border-radius: 5px; + border-style: hidden; + margin: auto; + background-color: var(--color-bg-body); + margin-top: 20px; +} + +.servicereport.fs-normal td { + font-size: 18px; +} + +.servicereport.fs-small td { + font-size: 14px; +} + +.servicereport thead { + background-color: var(--color-selected-bg); + color: var(--color-bg-body); +} + +.servicereport td { + padding: 5px 15px; +} + +.servicereport thead td { + font-weight: bold; +} + +.servicereport tbody td.success { + text-decoration: underline; + text-decoration-thickness: 2px; + text-decoration-color: #3ead48; + text-underline-offset: 2px; +} + +.servicereport tbody td.warning { + text-decoration: underline; + text-decoration-thickness: 2px; + text-decoration-color: #ffc107; + text-underline-offset: 2px; +} + +.servicereport tbody td.error { + text-decoration: underline; + text-decoration-thickness: 2px; + text-decoration-color: #d1232a; + text-underline-offset: 2px; +} + +.servicereport .col-key { + width: 70%; +} + +.servicereport .col-value { + width: 30%; +} + +.servicereport--details tbody tr { + border-bottom: 1px solid #035754; +} + +.servicereport--striped tbody tr:nth-child(odd) { + background-color: #f3fafa; +} + +.servicereport--striped tbody tr:nth-child(even) { + background-color: #e7f6f6; +} + +.servicereport--striped tbody tr { + border-bottom: 1px solid #9bdcd9; +} + +.service_summary { + background-image: linear-gradient(#e7f6f6, #fafdfd); + margin-top: 20px; + padding-bottom: 15px; +} + +.service_summary__title { + background-color: #035754; + color: var(--color-bg-body); + font-weight: bold; + padding: 5px 15px; +} + +.service_notes { + margin: 15px 15px 0 15px; + padding: 15px; + background-color: var(--color-bg-body); + color: #035754; +} + +h4.label { + padding: 5px 15px; + background-color: #035754; + color: var(--color-bg-body); + margin-top: 20px; + margin-bottom: 20px; +} + +.text-center { + text-align: center; +} + +@media screen and (max-width: 600px) { +#support_btn { + display:none; + } +} +.form-popup { + display: none; + position: fixed; + bottom: 0; + right: 15px; + z-index: 9; +} + +.close { + position: absolute; + top: 0px; + right: 0px; +} + +#support_btn img:hover{ + transform: scale(1.5); +} + +.cancel_link { + white-space: nowrap; + text-align: center; + background: #b44a4a; + border: 0; + padding: 5px 0; + font-size: 9px; + margin-top: 5px; + cursor: pointer; + border-radius: 4px; +} + +.order-detail input { + border: 0; + border-bottom: 1px solid var(--color-tab-bg) +} + +.loading-container { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(255, 255, 255, 0.8); + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + z-index: 9999; + opacity: 0; + visibility: hidden; + transition: opacity 0.3s, visibility 0.3s; +} + +.loading-container.active { + opacity: 1; + visibility: visible; +} + +.loading-bar { + width: 200px; + height: 10px; + background-color: #f0f0f0; + border-radius: 5px; + overflow: hidden; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); +} + +.progress { + height: 100%; + width: 0%; + background-color: #4caf50; + animation: progressAnimation 2s infinite ease-in-out; +} + +.loading-text { + margin-top: 10px; + font-size: 14px; + color: #333; +} + +@keyframes progressAnimation { + 0% { width: 0%; } + 50% { width: 100%; } + 100% { width: 0%; } +} + +/* Hide the loading bar when page is loaded */ +.loaded .loading-container { + display: none; +} + +.hidden { + display: none !important; +} + +/*CATALOG VIEW*/ + +.stock p { + font-size: 10px; + margin: auto; + padding: 5px; + width: fit-content; + border-radius: 5px; + color: white; +} + +.stock p:before { + content : '\1F4E6'; +} + +.filtersection { + display: flex; + margin: 0 auto; + background: white; + border-radius: 12px; + margin-bottom: 50px; + padding: 10px; + width: 95%; +} + +.filter-section { + width: 250px; + padding: 20px; + border-right: 1px solid #e0e0e0; +} + +.filter-section h2 { + margin-bottom: 15px; + color: #333; +} + +.filter-group { + margin-bottom: 20px; +} + +.filter-group label { + margin-bottom: 10px; +} + +.filter-group input[type="checkbox"] { + margin-right: 10px; +} + +/* Responsive Design */ +@media (max-width: 768px) { + .filtersection { + flex-direction: column; + text-align: center; + } + + .filter-section { + width: 100%; + border-right: none; + border-bottom: 1px solid #e0e0e0; + } +} + +main .recentlyadded .products .product, main .products .products-wrapper .product { + display: block; + overflow: hidden; + text-decoration: none; + padding-bottom: 30px; + text-align: center; + margin: 5px; +} + +main .recentlyadded .products .product img, main .products .products-wrapper .product img { + transform: scale(1); + transition: transform 1s; +} + +main .products .product .name, main .products .products-wrapper .product .name { + display: block; + color: var(--color-text-default); + padding: 20px 0 2px 0; + text-align: center; + font-family: 'gerb'; + word-wrap: break-word; +} +main .products .product .price, main .products .products-wrapper .product .price { + display: block; + color: #999999; + text-align: center; +} + +.product .rrp { + color: #bbbbbb; + text-decoration: line-through; + font-size: 22px; + padding-left: 10px; +} + +.img_config { + border-radius:5px; + width: 25px; + height: 25px; + margin: 1px; +} + +/* Button alignment styles */ +.form-actions, +.modal-actions, +.dialog-actions, +.button-actions { + display: flex; + gap: 10px; + justify-content: flex-end; + align-items: center; + margin-top: 20px; +} + +.title-actions { + display: flex; + gap: 10px; + align-items: center; + justify-content: flex-end; +} + +.filter-actions { + display: flex; + gap: 10px; + justify-content: flex-end; + align-items: center; + flex-wrap: wrap; +} + +main .form .button-container, +main .form .form-actions, +main .content-block .button-container { + display: flex; + gap: 10px; + justify-content: flex-end; + align-items: center; + margin-top: 15px; +} + +.dialog .content .footer, +.modal .modal-footer { + display: flex; + gap: 10px; + justify-content: flex-end; + align-items: center; + padding: 20px; + border-top: 1px solid #eee; +} \ No newline at end of file diff --git a/custom/morvalwatches/style/veliti_intro.png b/custom/morvalwatches/style/veliti_intro.png new file mode 100644 index 0000000..60b2864 Binary files /dev/null and b/custom/morvalwatches/style/veliti_intro.png differ diff --git a/factuur.php b/factuur.php new file mode 100644 index 0000000..f394609 --- /dev/null +++ b/factuur.php @@ -0,0 +1,151 @@ + 'NL', + 'BE' => 'NL', + 'US' => 'US', + 'GB' => 'US', + 'DE' => 'DE', + 'FR' => 'FR', + 'ES' => 'ES' +]; + +$invoice_language = 'US'; // Default +if (!empty($invoice_data['customer']['language'])) { + $invoice_language = strtoupper($invoice_data['customer']['language']); +} elseif (!empty($invoice_data['customer']['country']) && isset($available_languages[strtoupper($invoice_data['customer']['country'])])) { + $invoice_language = $available_languages[strtoupper($invoice_data['customer']['country'])]; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Generate invoice HTML +//+++++++++++++++++++++++++++++++++++++++++++++++++++++ + +var_dump($invoice_data); +list($data, $customer_email, $order_id) = generateSoftwareInvoice($invoice_data, $order_number, $invoice_language); + +//+++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Check for HTML output request +//+++++++++++++++++++++++++++++++++++++++++++++++++++++ +if (isset($_GET['output']) && $_GET['output'] === 'html') { + // Output HTML directly to browser + echo $data; + exit; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Initialize DomPDF +//+++++++++++++++++++++++++++++++++++++++++++++++++++++ +use Dompdf\Dompdf; +use Dompdf\Options; + +$options = new Options(); +$options->set('isRemoteEnabled', true); +$dompdf = new Dompdf($options); + +// Load HTML content +$dompdf->loadHtml($data); + +// Setup paper size and orientation +$dompdf->setPaper('A4', 'portrait'); + +// Render the HTML as PDF +$dompdf->render(); + +$file_name = 'Factuur - ' . $order_id; + +//+++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Handle different actions +//+++++++++++++++++++++++++++++++++++++++++++++++++++++ + +// Email invoice to customer +if (isset($_POST['email_invoice'])) { + $to = $customer_email; + $subject = 'Factuur - ' . $order_id; + $message = $data; + $attachment = $dompdf->output(); + $attachment_name = $file_name . '.pdf'; + + $header_redirect = 'Location: index.php?page=order&id=' . $order_id . '&success=invoice_sent'; + + // Send to PHPMailer + send_mail($to, $subject, $message, $attachment, $attachment_name); + + header($header_redirect); + exit; +} + +// Email invoice to admin/bookkeeping +if (isset($_POST['email_invoice_to_admin'])) { + $to = $customer_email; + $subject = 'Factuur - ' . $order_id; + $message = $data; + $attachment = $dompdf->output(); + $attachment_name = $file_name . '.pdf'; + + $header_redirect = 'Location: index.php?page=order&id=' . $order_id . '&success=invoice_sent_admin'; + + // Send to bookkeeping if configured + if (defined('invoice_bookkeeping') && invoice_bookkeeping && defined('email_bookkeeping') && email_bookkeeping) { + send_mail(email_bookkeeping, $subject, $message, $attachment, $attachment_name); + } + + header($header_redirect); + exit; +} + +// Show invoice in browser +if (isset($_POST['show_invoice'])) { + // Clean output buffer to prevent corrupted PDF + if (ob_get_level()) { + ob_end_clean(); + } + + // Stream PDF to browser + $dompdf->stream($file_name . ".pdf", array("Attachment" => false)); + exit; +} + +// If no action specified, redirect back +header('Location: index.php?page=order&id=' . $order_number); +exit; + +?> \ No newline at end of file diff --git a/histories.php b/histories.php index 2aa3ba3..b6f962e 100644 --- a/histories.php +++ b/histories.php @@ -30,16 +30,16 @@ $url = 'index.php?page=histories'.$status.$search; //GET Details from URL $GET_VALUES = urlGETdetails($_GET) ?? ''; //CALL TO API -$api_url = '/v1/history/'.$GET_VALUES; +$api_url = '/v2/history/'.$GET_VALUES; $responses = ioServer($api_url,''); //Decode Payload -if (!empty($responses)){$responses = decode_payload($responses);}else{$responses = null;} +if (!empty($responses)){$responses = json_decode($responses);}else{$responses = null;} //Return QueryTotal from API -$api_url = '/v1/history/'.$GET_VALUES.'&totals='; +$api_url = '/v2/history/'.$GET_VALUES.'&totals='; $query_total = ioServer($api_url,''); //Decode Payload -if (!empty($query_total)){$query_total = decode_payload($query_total);}else{$query_total = null;} +if (!empty($query_total)){$query_total = json_decode($query_total);}else{$query_total = null;} template_header('Histories', 'histories','view'); $view = ' @@ -116,7 +116,7 @@ $view .= ' foreach ($responses as $response){ $description = json_decode($response->description) ?? $response->description; - $description = json_encode($description, JSON_PRETTY_PRINT); + $description = json_encode($description, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); //Replace JSON ITEMS $search = ['{', '}', '"',':','[',']',',']; $replace = ['', '','','=','','','']; diff --git a/history.php b/history.php index 116b24f..9b207c9 100644 --- a/history.php +++ b/history.php @@ -33,16 +33,16 @@ $url = 'index.php?page=history&equipmentID='.$_GET['equipmentID'].$status.$searc //GET Details from URL $GET_VALUES = urlGETdetails($_GET) ?? ''; //CALL TO API -$api_url = '/v1/history/'.$GET_VALUES; +$api_url = '/v2/history/'.$GET_VALUES; $responses = ioServer($api_url,''); //Decode Payload -if (!empty($responses)){$responses = decode_payload($responses);}else{$responses = null;} +if (!empty($responses)){$responses = json_decode($responses);}else{$responses = null;} //Return QueryTotal from API -$api_url = '/v1/history/'.$GET_VALUES.'&totals='; +$api_url = '/v2/history/'.$GET_VALUES.'&totals='; $query_total = ioServer($api_url,''); //Decode Payload -if (!empty($query_total)){$query_total = decode_payload($query_total);}else{$query_total = null;} +if (!empty($query_total)){$query_total = json_decode($query_total);}else{$query_total = null;} // Handle success messages @@ -137,7 +137,7 @@ $view .= ' foreach ($responses as $response){ $description = json_decode($response->description) ?? $response->description; -$description = json_encode($description, JSON_PRETTY_PRINT); +$description = json_encode($description, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); //Replace JSON ITEMS $search = ['{', '}', '"',':','[',']',',']; diff --git a/history_manage.php b/history_manage.php index 54a97e3..2403cae 100644 --- a/history_manage.php +++ b/history_manage.php @@ -34,10 +34,10 @@ if ($rowID !=''){ if (isset($_GET['rowID'])) { // ID param exists, edit an existing product //CALL TO API - $api_url = '/v1/history/historyid='.$rowID; + $api_url = '/v2/history/historyid='.$rowID; $responses = ioServer($api_url,''); //Decode Payload - if (!empty($responses)){$responses = decode_payload($responses);}else{$responses = null;} + if (!empty($responses)){$responses = json_decode($responses);}else{$responses = null;} $history = json_decode(json_encode($responses[0]), true); diff --git a/settings/translations/translations_DE.php b/settings/translations/translations_DE.php index 091bfef..f5c811e 100644 --- a/settings/translations/translations_DE.php +++ b/settings/translations/translations_DE.php @@ -319,6 +319,21 @@ $firmwaretool_step_5 = 'Wenn Firmware verfügbar ist: Die Statusleiste zeigt " Ik bevestig dat SN en HW zijn uitgelezen van de activa.'; $firmwaretool_step_7 = 'Druk op de "Update firmware" knop om de update te starten en de instructies op het scherm te volgen'; $firmwaretool_step_8 = 'Opgelet: Dit proces kan niet onderbroken worden.'; +$softwaretool_h2 = 'Software upgrade tool'; +$softwaretool_p = 'Software upgrade opties.'; +$softwaretool_step = 'Instructies'; +$softwaretool_step_1 = 'Sluit het apparaat via USB aan op de computer.(USB bevindt zich onder de batterijklep)'; +$softwaretool_step_2 = 'Druk "connect" knop'; +$softwaretool_step_3 = 'In het popup venster selecteer het apparaat door er op te klikken. Druk daarna op de verbinding maken knop.'; +$softwaretool_step_4 = 'Het apparaat wordt nu gelezen. Een voortgang status wordt getoond'; +$softwaretool_step_5 = 'Beschikbare software upgrades worden weergegeven met Naam, Beschrijving en Prijs'; +$softwaretool_step_6 = 'Selecteer een software versie'; +$softwaretool_step_7 = 'Voor betaalde upgrades, volg het betalingsproces'; +$softwaretool_step_8 = 'Opgelet: Dit proces kan niet onderbroken worden.'; +$softwaretool_no_updates = 'Geen software updates gevonden'; +$softwaretool_checking = 'Controleren op software updates...'; +$softwaretool_available = 'Software updates beschikbaar'; +$softwaretool_select_upgrade = 'Selecteer een upgrade optie:'; $newuser_subject = 'CustomerPortal user created'; $newuser_header = 'Dear CustomerPortal user'; $newuser_text = 'Your CustomerPortal administrator has provided access to the CustomerPortal. To complete your account you need to update your password via the link below.'; diff --git a/settings/translations/translations_PL.php b/settings/translations/translations_PL.php index f07f593..63abeed 100644 --- a/settings/translations/translations_PL.php +++ b/settings/translations/translations_PL.php @@ -319,6 +319,21 @@ $firmwaretool_step_5 = 'Gdy oprogramowanie jest dostępne: Pasek stanu pokaże " $firmwaretool_step_6 = 'Gdy oprogramowanie jest dostępne: Upewnij się, że SN i HW zostały odczytane z urządzenia i potwierdź to zaznaczając pole "Potwierdzam, że SN i HW zostały odczytane z urządzenia"'; $firmwaretool_step_7 = 'Naciśnij przycisk "Aktualizuj oprogramowanie", aby uruchomić okno aktualizacji oprogramowania i postępuj zgodnie z instrukcjami na ekranie'; $firmwaretool_step_8 = 'Uwaga: Ten proces nie może zostać przerwany i musi się zakończyć.'; +$softwaretool_h2 = 'Narzędzie aktualizacji oprogramowania'; +$softwaretool_p = 'Opcje aktualizacji oprogramowania.'; +$softwaretool_step = 'Instrukcje'; +$softwaretool_step_1 = 'Podłącz urządzenie do komputera przez USB. (Znajduje się pod pokrywą baterii)'; +$softwaretool_step_2 = 'Naciśnij przycisk "połącz"'; +$softwaretool_step_3 = 'Pojawi się okno popup z prośbą o wybranie urządzenia. Wybierz urządzenie klikając na nie, a następnie naciśnij przycisk połącz.'; +$softwaretool_step_4 = 'Po zniknięciu okna popup urządzenie zostanie odczytane, pasek stanu pokaże postęp'; +$softwaretool_step_5 = 'Dostępne aktualizacje oprogramowania zostaną wyświetlone z Nazwą, Opisem i Ceną'; +$softwaretool_step_6 = 'Wybierz wersję oprogramowania'; +$softwaretool_step_7 = 'W przypadku płatnych aktualizacji postępuj zgodnie z procesem płatności'; +$softwaretool_step_8 = 'Uwaga: Ten proces nie może zostać przerwany i musi się zakończyć.'; +$softwaretool_no_updates = 'Nie znaleziono aktualizacji oprogramowania'; +$softwaretool_checking = 'Sprawdzanie aktualizacji oprogramowania...'; +$softwaretool_available = 'Dostępne aktualizacje oprogramowania'; +$softwaretool_select_upgrade = 'Wybierz opcję aktualizacji:'; $newuser_subject = 'Użytkownik CustomerPortal utworzony'; $newuser_header = 'Szanowny użytkowniku CustomerPortal'; $newuser_text = 'Administrator CustomerPortal przyznał Ci dostęp do CustomerPortal. Aby ukończyć konfigurację konta, musisz zaktualizować hasło za pomocą poniższego linku.'; diff --git a/settings/translations/translations_PT.php b/settings/translations/translations_PT.php index 1f7fd5d..0858309 100644 --- a/settings/translations/translations_PT.php +++ b/settings/translations/translations_PT.php @@ -319,6 +319,21 @@ $firmwaretool_step_5 = 'Quando o firmware estiver disponível: A barra de status $firmwaretool_step_6 = 'Quando o firmware estiver disponível: Certifique-se de que o SN e o HW sejam lidos do dispositivo e confirme isso selecionando a caixa "Eu confirmo que o SN e o HW foram lidos do dispositivo"'; $firmwaretool_step_7 = 'Pressione o botão "Atualizar firmware" para iniciar o diálogo de atualização de firmware e siga as instruções na tela'; $firmwaretool_step_8 = 'Esteja ciente: Este processo não pode ser interrompido e precisa ser concluído.'; +$softwaretool_h2 = 'Ferramenta de atualização de software'; +$softwaretool_p = 'Opções de atualização de software.'; +$softwaretool_step = 'Instruções'; +$softwaretool_step_1 = 'Conecte o dispositivo ao computador por USB. (Encontrado sob a tampa da bateria)'; +$softwaretool_step_2 = 'Pressione o botão "conectar"'; +$softwaretool_step_3 = 'Um popup aparecerá pedindo para selecionar um dispositivo. Selecione o dispositivo clicando nele e depois pressione o botão conectar.'; +$softwaretool_step_4 = 'Após o popup desaparecer, o dispositivo será lido, a barra de status mostrará o progresso'; +$softwaretool_step_5 = 'Atualizações de software disponíveis serão exibidas com Nome, Descrição e Preço'; +$softwaretool_step_6 = 'Selecione uma versão de software'; +$softwaretool_step_7 = 'Para atualizações pagas, siga o processo de pagamento'; +$softwaretool_step_8 = 'Esteja ciente: Este processo não pode ser interrompido e precisa ser concluído.'; +$softwaretool_no_updates = 'Nenhuma atualização de software encontrada'; +$softwaretool_checking = 'Verificando atualizações de software...'; +$softwaretool_available = 'Atualizações de software disponíveis'; +$softwaretool_select_upgrade = 'Selecione uma opção de atualização:'; $newuser_subject = 'Usuário do CustomerPortal criado'; $newuser_header = 'Caro usuário do CustomerPortal'; $newuser_text = 'Seu administrador do CustomerPortal forneceu acesso ao CustomerPortal. Para completar sua conta, você precisa atualizar sua senha através do link abaixo.'; diff --git a/settings/translations/translations_US.php b/settings/translations/translations_US.php index 2daac2d..1858eb1 100644 --- a/settings/translations/translations_US.php +++ b/settings/translations/translations_US.php @@ -336,8 +336,8 @@ $softwaretool_step_2 = 'Press "connect" button"'; $softwaretool_step_3 = 'A popup will appear asking to select a device. Select the device by clicking on it and the press the connect button.'; $softwaretool_step_4 = 'After pop-up disappears the device will be read, status bar will show progress'; $softwaretool_step_5 = 'Available software upgrades will be displayed with Name, Description and Price'; -$softwaretool_step_6 = 'Select a free upgrade (price = 0) to download and install'; -$softwaretool_step_7 = 'For paid upgrades, please contact support'; +$softwaretool_step_6 = 'Select a software version'; +$softwaretool_step_7 = 'For paid upgrades, please follow the payment process'; $softwaretool_step_8 = 'Be aware: This process cannot be stopped and needs to finish.'; $softwaretool_no_updates = 'No software updates found'; $softwaretool_checking = 'Checking for software updates...'; diff --git a/softwaretool.php b/softwaretool.php index c419d56..e259d50 100644 --- a/softwaretool.php +++ b/softwaretool.php @@ -122,7 +122,7 @@ $view .= '
@@ -143,10 +143,10 @@ $view .= '
- @@ -245,6 +247,108 @@ echo ' closePaymentModal(); } }); + + // Monitor upload completion + const observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + if (mutation.type === "attributes" && mutation.attributeName === "checked") { + const actionFirmware = document.getElementById("action_firmware"); + if (actionFirmware && actionFirmware.checked) { + console.log("Upload completion detected!"); + // Upload completed successfully + handleUploadCompletion(true); + } + } + }); + }); + + // Also monitor for readBar changes to detect completion + const readBarObserver = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + if (mutation.type === "childList" || mutation.type === "characterData") { + const readBar = document.getElementById("readBar"); + if (readBar && readBar.innerHTML && readBar.innerHTML.includes("Firmware update completed")) { + console.log("Firmware update completed detected via readBar!"); + setTimeout(() => handleUploadCompletion(true), 500); + } + } + }); + }); + + // Start observing when upload section is visible + function startUploadMonitoring() { + const actionFirmware = document.getElementById("action_firmware"); + const readBar = document.getElementById("readBar"); + + if (actionFirmware) { + observer.observe(actionFirmware, { + attributes: true, + attributeFilter: ["checked"] + }); + console.log("Started monitoring action_firmware checkbox"); + } + + if (readBar) { + readBarObserver.observe(readBar, { + childList: true, + subtree: true, + characterData: true + }); + console.log("Started monitoring readBar for completion"); + } + } + + // Handle upload completion (success or failure) + window.handleUploadCompletion = function(success) { + console.log("handleUploadCompletion called with success:", success); + + const installStatus = document.getElementById("installationStatus"); + const readBar = document.getElementById("readBar"); + + if (success) { + // Success handling + console.log("Updating UI for successful completion"); + if (installStatus) { + installStatus.innerHTML = \'\' + + \'\' + + \'

Installation Complete!

\' + + \'

Your device has been successfully updated

\'; + } + // Ensure progress bar is at 100% + if (readBar) { + readBar.style.width = "100%"; + readBar.style.background = "#04AA6D"; + readBar.innerHTML = "Firmware update completed - 100%"; + console.log("Updated readBar to 100%"); + } + } else { + // Failure handling + console.log("Updating UI for failed completion"); + if (installStatus) { + installStatus.innerHTML = \'\' + + \'\' + + \'

Installation Failed

\' + + \'

Please try again or contact support

\'; + } + if (readBar) { + readBar.style.width = "100%"; + readBar.style.background = "#dc3545"; + readBar.innerHTML = "Installation failed"; + } + } + + // Stop monitoring + observer.disconnect(); + readBarObserver.disconnect(); + console.log("Stopped monitoring observers"); + }; + + // Monitor for upload errors + window.addEventListener("error", function(e) { + if (e.message && e.message.includes("upload")) { + handleUploadCompletion(false); + } + }); '; template_footer();