Hotel Raxa - Advanced Booking System Implementation

🏨 Hotel Booking Enhancements:
- Implemented Eagle Booking Advanced Pricing add-on
- Added Booking.com-style rate management system
- Created professional calendar interface for pricing
- Integrated deals and discounts functionality

💰 Advanced Pricing Features:
- Dynamic pricing models (per room, per person, per adult)
- Base rates, adult rates, and child rates management
- Length of stay discounts and early bird deals
- Mobile rates and secret deals implementation
- Seasonal promotions and flash sales

📅 Availability Management:
- Real-time availability tracking
- Stop sell and restriction controls
- Closed to arrival/departure functionality
- Minimum/maximum stay requirements
- Automatic sold-out management

💳 Payment Integration:
- Maintained Redsys payment gateway integration
- Seamless integration with existing Eagle Booking
- No modifications to core Eagle Booking plugin

🛠️ Technical Implementation:
- Custom database tables for advanced pricing
- WordPress hooks and filters integration
- AJAX-powered admin interface
- Data migration from existing Eagle Booking
- Professional calendar view for revenue management

📊 Admin Interface:
- Booking.com-style management dashboard
- Visual rate and availability calendar
- Bulk operations for date ranges
- Statistics and analytics dashboard
- Modal dialogs for quick editing

🔧 Code Quality:
- WordPress coding standards compliance
- Secure database operations with prepared statements
- Proper input validation and sanitization
- Error handling and logging
- Responsive admin interface

🤖 Generated with Claude Code (https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Hotel Raxa Dev
2025-07-11 07:43:22 +02:00
commit 5b1e2453c7
9816 changed files with 2784509 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
<?php
/**
* Redux Tabbed Extension Class
*
* @package Redux\Extensions\Tabbed
* @author Kevin Provance <kevin.provance@gmail.com>
* @class Redux_Extension_Tabbed
*
* @version 4.4.8
*/
defined( 'ABSPATH' ) || exit;
// Don't duplicate me!
if ( ! class_exists( 'Redux_Extension_Tabbed' ) ) {
/**
* Class Redux_Extension_Tabbed
*/
class Redux_Extension_Tabbed extends Redux_Extension_Abstract {
/**
* Extension version.
*
* @var string
*/
public static $version = '4.4.8';
/**
* Extension friendly name.
*
* @var string
*/
public $extension_name = 'Tabbed';
/**
* Class Constructor. Defines the args for the extensions class
*
* @since 1.0.0
* @access public
*
* @param object $redux Parent settings.
*
* @return void
*/
public function __construct( $redux ) {
parent::__construct( $redux, __FILE__ );
$this->add_field( 'tabbed' );
}
}
}

View File

@@ -0,0 +1,216 @@
<?php
/**
* Tabbed Field
*
* @package Redux Framework\Tabbed
* @author Kevin Provance (kprovance)
* @version 4.4.8
*/
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( 'Redux_Tabbed', false ) ) {
/**
* Class Redux_Tabbed
*/
class Redux_Tabbed extends Redux_Field {
/**
* Set field defaults.
*/
public function set_defaults() {
$defaults = array(
'icon' => '',
);
$this->field = wp_parse_args( $this->field, $defaults );
}
/**
* Field Render Function.
* Takes the vars and outputs the HTML for the field in the settings
*
* @since ReduxFramework 0.0.4
*/
public function render() {
$unallowed = array( 'tabbed', 'social_profiles', 'color_schemes', 'repeater' );
echo '<div id="' . esc_attr( $this->field['id'] ) . '-tabbed" class="redux-tabbed" rel="' . esc_attr( $this->field['id'] ) . '">';
echo '<div class="redux-tabbed-nav" data-id="' . esc_attr( $this->field['id'] ) . '">';
foreach ( $this->field['tabs'] as $key => $tab ) {
$tabbed_icon = ( ! empty( $tab['icon'] ) ) ? '<i class="redux-tab-icon ' . esc_attr( $tab['icon'] ) . '"></i>' : '';
$tabbed_active = ( empty( $key ) ) ? 'redux-tabbed-active' : '';
// Output HTML escaped above.
// phpcs:ignore WordPress.Security.EscapeOutput
echo '<a href="#" class="' . esc_attr( $tabbed_active ) . '"">' . $tabbed_icon . esc_attr( $tab['title'] ) . '</a>';
}
echo '</div>';
echo '<div class="redux-tabbed-contents">';
foreach ( $this->field['tabs'] as $key => $tab ) {
$tabbed_hidden = ( ! empty( $key ) ) ? ' hidden' : '';
echo '<div class="redux-tabbed-content' . esc_attr( $tabbed_hidden ) . '">';
foreach ( $tab['fields'] as $field ) {
if ( in_array( $field['type'], $unallowed, true ) ) {
echo esc_html__( 'The', 'redux-framework' ) . ' <code>' . esc_html( $field['type'] ) . '</code> ' . esc_html__( 'field is not supported within the Tabbed field.', 'redux-framework' );
} else {
$this->output_field( $field );
}
}
echo '</div>';
}
echo '</div>';
echo '</div>';
}
/**
* Output field.
*
* @param array $field Field array.
*/
public function output_field( array $field ) {
$this->enqueue_dependencies( $field );
if ( ! isset( $field['class'] ) ) {
$field['class'] = '';
}
$field['class'] .= ' tabbed';
echo '<div class="redux-tab-field">';
if ( ! empty( $field['title'] ) ) {
echo '<div class="redux-field-title">';
echo '<h4>' . wp_kses_post( $field['title'] ) . '</h4>';
if ( ! empty( $field['subtitle'] ) ) {
echo '<div class="redux-field-subtitle">' . wp_kses_post( $field['subtitle'] ) . '</div>';
}
echo '</div>';
}
$orig_field_id = $field['id'];
$field['name'] = $this->parent->args['opt_name'] . '[' . $orig_field_id . ']';
$field['class'] .= ' in-tabbed';
if ( isset( $field['options'] ) ) {
// Sorter data filter.
if ( 'sorter' === $field['type'] && ! empty( $field['data'] ) && is_array( $field['data'] ) ) {
if ( ! isset( $field['args'] ) ) {
$field['args'] = array();
}
foreach ( $field['data'] as $key => $data ) {
if ( ! isset( $field['args'][ $key ] ) ) {
$field['args'][ $key ] = array();
}
$field['options'][ $key ] = $this->parent->get_wordpress_data( $data, $field['args'][ $key ] );
}
}
}
$default = $field['default'] ?? '';
$value = empty( $this->parent->options[ $orig_field_id ] ) ? $default : $this->parent->options[ $orig_field_id ];
$this->parent->render_class->field_input( $field, $value );
echo '<div class="clear"></div>';
echo '</div>';
}
/**
* Localize.
*
* @param array $field Field.
* @param string $value Value.
*
* @return void
*/
public function localize( array $field, string $value = '' ) {
ob_start();
foreach ( $field['tabs'] as $f ) {
foreach ( $f['fields'] as $field ) {
$this->output_field( $field );
}
}
ob_end_clean();
}
/**
* Enqueue Deps.
*
* @param array $field Field.
*/
private function enqueue_dependencies( array $field ) {
$field_type = $field['type'];
$field_class = 'Redux_' . $field_type;
if ( ! class_exists( $field_class ) ) {
$field_type = str_replace( '_', '-', $field_type );
// phpcs:ignore WordPress.NamingConventions.ValidHookName
$class_file = apply_filters( 'redux-typeclass-load', ReduxFramework::$_dir . 'inc/fields/' . $field_type . '/class-redux-' . $field_type . '.php', $field_class );
if ( file_exists( $class_file ) ) {
require_once $class_file;
}
}
if ( class_exists( $field_class ) && method_exists( $field_class, 'enqueue' ) ) {
$enqueue = new $field_class( '', '', $this->parent );
$enqueue->enqueue();
}
if ( class_exists( $field_class ) && method_exists( $field_class, 'localize' ) ) {
$enqueue = new $field_class( '', '', $this->parent );
$data = $enqueue->localize( $field );
$this->parent->enqueue_class->localize_data[ $field['type'] ][ $field['id'] ] = $data;
}
}
/**
* Enqueue Function.
* If this field requires any scripts, or css define this function and register/enqueue the scripts/css
*
* @since ReduxFramework 0.0.4
*/
public function enqueue() {
wp_enqueue_script(
'redux-field-tabbed',
Redux_Core::$url . 'inc/extensions/tabbed/tabbed/redux-tabbed' . Redux_Functions::is_min() . '.js',
array( 'jquery', 'redux-js' ),
Redux_Extension_Tabbed::$version,
true
);
if ( $this->parent->args['dev_mode'] ) {
wp_enqueue_style(
'redux-field-tabbed',
Redux_Core::$url . 'inc/extensions/tabbed/tabbed/redux-tabbed.css',
array(),
Redux_Extension_Tabbed::$version
);
}
}
}
}

View File

@@ -0,0 +1,29 @@
.redux-container-tabbed .redux-tabbed-content { border: 1px solid #ccd0d4; background-color: #fff; -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); }
.redux-container-tabbed .redux-tabbed-content > .redux-tab-field { padding: 15px; }
.redux-container-tabbed .redux-tabbed-content > .redux-tab-field.hide { display: none; }
.redux-container-tabbed .redux-tabbed-nav .redux-tab-icon { padding-right: 5px; }
.redux-container-tabbed .redux-tabbed-nav a { display: inline-block; padding: 12px 15px; margin-top: 1px; margin-right: 5px; margin-bottom: -1px; position: relative; text-decoration: none; color: #444; font-weight: 600; border: 1px solid #ccd0d4; background-color: #f3f3f3; -webkit-transition: all .2s; transition: all .2s; }
.redux-container-tabbed .redux-tabbed-nav a:hover { background-color: #f9f9f9; }
.redux-container-tabbed .redux-tabbed-nav a.redux-tabbed-active { background-color: #fff; border-bottom-color: #fff; }
.redux-container-tabbed .redux-tabbed-nav a:focus { outline: none; -webkit-box-shadow: none; box-shadow: none; }
.redux-container-tabbed .redux-tab-field + .redux-tab-field { border-top: 1px solid #eee; }
.redux-container-tabbed .redux-field-title { position: relative; width: 20%; float: left; }
.redux-container-tabbed .redux-field-title h4 { margin-bottom: 0; }
.redux-container-tabbed .redux-field-subtitle { margin-top: 6px; font-weight: 400; color: #999; }
.redux-container-tabbed .description { color: #999; }
/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdXgtdGFiYmVkLmNzcyIsInNvdXJjZXMiOlsicmVkdXgtdGFiYmVkLnNjc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsQUFDSSx1QkFEbUIsQ0FDbkIscUJBQXFCLENBQUMsRUFDbEIsTUFBTSxFQUFFLGlCQUFpQixFQUN6QixnQkFBZ0IsRUFBRSxJQUFJLEVBQ3RCLFVBQVUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsR0FDNUM7O0FBTEwsQUFPSSx1QkFQbUIsQ0FPbkIscUJBQXFCLEdBQUcsZ0JBQWdCLENBQUMsRUFDckMsT0FBTyxFQUFFLElBQUksR0FLaEI7O0FBYkwsQUFVUSx1QkFWZSxDQU9uQixxQkFBcUIsR0FBRyxnQkFBZ0IsQUFHbkMsS0FBSyxDQUFDLEVBQ0gsT0FBTyxFQUFFLElBQUksR0FDaEI7O0FBWlQsQUFlSSx1QkFmbUIsQ0FlbkIsaUJBQWlCLENBQUMsZUFBZSxDQUFDLEVBQzlCLGFBQWEsRUFBRSxHQUFHLEdBQ3JCOztBQWpCTCxBQW1CSSx1QkFuQm1CLENBbUJuQixpQkFBaUIsQ0FBQyxDQUFDLENBQUMsRUFDaEIsT0FBTyxFQUFFLFlBQVksRUFDckIsT0FBTyxFQUFFLFNBQVMsRUFDbEIsVUFBVSxFQUFFLEdBQUcsRUFDZixZQUFZLEVBQUUsR0FBRyxFQUNqQixhQUFhLEVBQUUsSUFBSSxFQUNuQixRQUFRLEVBQUUsUUFBUSxFQUNsQixlQUFlLEVBQUUsSUFBSSxFQUNyQixLQUFLLEVBQUUsSUFBSSxFQUNYLFdBQVcsRUFBRSxHQUFHLEVBQ2hCLE1BQU0sRUFBRSxpQkFBaUIsRUFDekIsZ0JBQWdCLEVBQUUsT0FBTyxFQUN6QixVQUFVLEVBQUUsT0FBTyxHQUN0Qjs7QUFoQ0wsQUFrQ0ksdUJBbENtQixDQWtDbkIsaUJBQWlCLENBQUMsQ0FBQyxBQUFBLE1BQU0sQ0FBQyxFQUN0QixnQkFBZ0IsRUFBRSxPQUFPLEdBQzVCOztBQXBDTCxBQXNDSSx1QkF0Q21CLENBc0NuQixpQkFBaUIsQ0FBQyxDQUFDLEFBQUEsb0JBQW9CLENBQUMsRUFDcEMsZ0JBQWdCLEVBQUUsSUFBSSxFQUN0QixtQkFBbUIsRUFBRSxJQUFJLEdBQzVCOztBQXpDTCxBQTJDSSx1QkEzQ21CLENBMkNuQixpQkFBaUIsQ0FBQyxDQUFDLEFBQUEsTUFBTSxDQUFDLEVBQ3RCLE9BQU8sRUFBRSxJQUFJLEVBQ2IsVUFBVSxFQUFFLElBQUksR0FDbkI7O0FBOUNMLEFBZ0RJLHVCQWhEbUIsQ0FnRG5CLGdCQUFnQixHQUFHLGdCQUFnQixDQUFDLEVBQ2hDLFVBQVUsRUFBRSxjQUFjLEdBQzdCOztBQWxETCxBQW9ESSx1QkFwRG1CLENBb0RuQixrQkFBa0IsQ0FBQyxFQUNmLFFBQVEsRUFBRSxRQUFRLEVBQ2xCLEtBQUssRUFBRSxHQUFHLEVBQ1YsS0FBSyxFQUFFLElBQUksR0FLZDs7QUE1REwsQUF5RFEsdUJBekRlLENBb0RuQixrQkFBa0IsQ0FLZCxFQUFFLENBQUMsRUFDQyxhQUFhLEVBQUUsQ0FBQyxHQUNuQjs7QUEzRFQsQUE4REksdUJBOURtQixDQThEbkIscUJBQXFCLENBQUMsRUFDbEIsVUFBVSxFQUFFLEdBQUcsRUFDZixXQUFXLEVBQUUsR0FBRyxFQUNoQixLQUFLLEVBQUUsSUFBSSxHQUNkOztBQWxFTCxBQW9FSSx1QkFwRW1CLENBb0VuQixZQUFZLENBQUMsRUFDVCxLQUFLLEVBQUUsSUFBSSxHQUNkIn0= */
/*# sourceMappingURL=redux-tabbed.css.map */

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,343 @@
/*global redux*/
/**
* Tabbed
* Dependencies : jquery
* Feature added by : Kevin Provance (kprovance)
* Date : 09.18.2023
*/
(function ( $ ) {
'use strict';
var reduxObject;
redux.field_objects = redux.field_objects || {};
redux.field_objects.tabbed = redux.field_objects.tabbed || {};
redux.field_objects.tabbed.getOptName = function ( el ) {
var optName;
optName = el.parents().find( '.redux-ajax-security' ).data( 'opt-name' );
if ( undefined === optName ) {
optName = el.parents( '.redux-container' ).data( 'opt-name' );
}
if ( undefined === optName ) {
return redux;
} else {
return redux.optName;
}
};
redux.field_objects.tabbed.init = function ( selector ) {
selector = $.redux.getSelector( selector, 'tabbed' );
$( selector ).each(
function () {
var el = $( this );
var parent = el;
if ( ! el.hasClass( 'redux-field-container' ) ) {
parent = el.parents( '.redux-field-container:first' );
}
if ( parent.is( ':hidden' ) ) {
return;
}
if ( parent.hasClass( 'redux-field-init' ) ) {
parent.removeClass( 'redux-field-init' );
} else {
return;
}
reduxObject = redux.field_objects.tabbed.getOptName( el );
el.find( '.redux-tabbed' ).each(
function () {
var $this = el;
var links = $this.find( '.redux-tabbed-nav a' );
var contents = $this.find( '.redux-tabbed-content' );
$.redux.initFields();
links.on(
'click',
function ( e ) {
e.preventDefault();
var link = $( this );
var index = link.index();
var content = contents.eq( index );
link.addClass( 'redux-tabbed-active' ).siblings().removeClass( 'redux-tabbed-active' );
content.removeClass( 'hidden' ).siblings().addClass( 'hidden' );
$.redux.initFields();
}
);
}
);
}
);
};
redux.field_objects.tabbed.check_parents_dependencies = function ( id ) {
var show = '';
if ( reduxObject.required_child.hasOwnProperty( id ) ) {
$.each(
reduxObject.required_child[id],
function ( i, parentData ) {
var parentValue;
var value;
var idx;
var x;
i = null;
idx = $( '#' + reduxObject.args.opt_name + '-' + parentData.parent );
if ( idx.hasClass( 'hide' ) ) {
show = false;
return false;
} else {
if ( false !== show ) {
value = idx.serializeForm();
if ( null !== value && 'object' === typeof value && value.hasOwnProperty( reduxObject.args.opt_name ) ) {
if ( undefined === value[reduxObject.args.opt_name][parentData.parent] ) {
x = Object.values( value[reduxObject.args.opt_name] )[0][parentData.parent];
} else {
x = value[reduxObject.args.opt_name][parentData.parent];
}
value = x;
}
if ( $( '#' + reduxObject.args.opt_name + '-' + id ).hasClass( 'redux-container-media' ) ) {
value = value.url;
}
parentValue = value;
show = $.redux.check_dependencies_visibility( parentValue, parentData );
return false;
}
}
}
);
} else {
show = true;
}
return show;
};
/* jshint -W117, -W098 */
/* jscs:disable disallowUnusedParams */
/* redux_hook(
$.redux,
'required',
function ( returnValue, originalFunction ) {
var reduxObj;
reduxObj = redux.field_objects.tabbed.getOptName( $( '.redux-container-tabbed' ) );
$.each(
reduxObj.folds,
function ( i, v ) {
var fieldset;
var div;
var rawTable;
fieldset = $( '[id^=' + reduxObj.args.opt_name + '-' + i + ']' );
if ( fieldset.find( '*' ).hasClass( 'in-tabbed' ) ) {
fieldset.addClass( 'fold' );
fieldset.parents( '.redux-tab-field' ).addClass( 'fold' );
if ( 'hide' === v ) {
fieldset.addClass( 'hide' );
fieldset.parents( '.redux-tab-field' ).addClass( 'hide' );
if ( fieldset.hasClass( 'redux-container-section' ) ) {
div = $( '#section-' + i );
if ( div.hasClass( 'redux-section-indent-start' ) ) {
$( '#section-table-' + i ).hide().addClass( 'hide' );
div.hide().addClass( 'hide' );
}
}
if ( fieldset.hasClass( 'redux-container-info' ) ) {
$( '#info-' + i ).hide().addClass( 'hide' );
}
if ( fieldset.hasClass( 'redux-container-divide' ) ) {
$( '#divide-' + i ).hide().addClass( 'hide' );
}
if ( fieldset.hasClass( 'redux-container-raw' ) ) {
rawTable = fieldset.parents().find( 'table#' + redux.args.opt_name + '-' + i );
rawTable.hide().addClass( 'hide' );
}
}
}
}
);
}
); */
/* redux_hook(
$.redux,
'required_recursive_hide',
function ( returnValue, originalFunction, id ) {
var div;
var rawTable;
var toFade;
var theId;
var reduxObj;
reduxObj = redux.field_objects.tabbed.getOptName( $( '.redux-container-tabbed' ) );
id = id[0];
theId = $( '#' + reduxObj.args.opt_name + '-' + id );
if ( theId.find( '*' ).hasClass( 'in-tabbed' ) ) {
toFade = theId.parents( '.redux-tab-field:first' );
if ( 0 === toFade ) {
toFade = theId.parents( 'li:first' );
}
toFade.fadeOut(
50,
function () {
$( this ).addClass( 'hide' );
//$( this ).prevUntil( '.redux-tab-field' ).addClass( 'hide' );
if ( theId.hasClass( 'redux-container-section' ) ) {
div = $( '#section-' + id );
if ( div.hasClass( 'redux-section-indent-start' ) ) {
$( '#section-table-' + id ).fadeOut( 50 ).addClass( 'hide' );
div.fadeOut( 50 ).addClass( 'hide' );
}
}
if ( theId.hasClass( 'redux-container-info' ) ) {
$( '#info-' + id ).fadeOut( 50 ).addClass( 'hide' );
}
if ( theId.hasClass( 'redux-container-divide' ) ) {
$( '#divide-' + id ).fadeOut( 50 ).addClass( 'hide' );
}
if ( theId.hasClass( 'redux-container-raw' ) ) {
rawTable = $( '#' + reduxObj.args.opt_name + '-' + id ).parents().find( 'table#' + reduxObj.args.opt_name + '-' + id );
rawTable.fadeOut( 50 ).addClass( 'hide' );
}
if ( reduxObject.required.hasOwnProperty( id ) ) {
$.each(
reduxObj.required[id],
function ( child ) {
$.redux.required_recursive_hide( child );
}
);
}
}
);
}
}
); */
/* redux_hook(
$.redux,
'check_dependencies',
function ( returnValue, originalFunction, variable ) {
var current;
var id;
var container;
var is_hidden;
current = $( variable[0] );
if ( $( variable ).hasClass( 'in-tabbed' ) ) {
current = $( variable[0] );
id = current.parents( '.redux-field:first' ).data( 'id' );
container = current.parents( '.redux-field-container:first' );
is_hidden = container.hasClass( 'hide' );
$.each(
reduxObject.required[id],
function ( child, dependents ) {
var current;
var show;
var childFieldset;
current = $( this );
show = false;
childFieldset = $( '#' + reduxObject.args.opt_name + '-' + child );
if ( ! is_hidden ) {
show = redux.field_objects.tabbed.check_parents_dependencies( child );
}
if ( true === show ) {
childFieldset.fadeIn(
300,
function () {
$( this ).removeClass( 'hide' );
//$( this ).prevUntil( 'fieldset' ).removeClass( 'hide' );
$( this ).parents( '.redux-tab-field' ).removeClass( 'hide' );
//console.log($( '#' + reduxObject.args.opt_name + '-' + child ));
//console.log($( '#' + reduxObject.args.opt_name + '-' + child ).children().first());
if ( reduxObject.required.hasOwnProperty( child ) ) {
$.redux.check_dependencies( $( '#' + reduxObject.args.opt_name + '-' + child ).children().first() );
}
$.redux.initFields();
}
);
} else {
childFieldset.fadeOut(
100,
function () {
$( this ).addClass( 'hide' );
//$( this ).prevUntil( 'fieldset' ).addClass( 'hide' );
$( this ).parents( '.redux-tab-field' ).addClass( 'hide' );
if ( reduxObject.required.hasOwnProperty( child ) ) {
$.redux.required_recursive_hide( child );
}
}
);
}
current.find( 'select, radio, input[type=checkbox]' ).trigger( 'change' );
//console.log(variable)
console.log(current.length);
console.log(Array.isArray(current));
if( current.length > 1 ){
$.each(
current,
function(i,v){
console.log(v)
//console.log(v.find( 'select, radio, input[type=checkbox]' ));
}
);
} else {
console.log(current.find( 'select, radio, input[type=checkbox]' ));
current.find( 'select, radio, input[type=checkbox]' ).trigger( 'change' );
}
}
);
}
}
); */
})( jQuery );

View File

@@ -0,0 +1 @@
!function(i){"use strict";var n;redux.field_objects=redux.field_objects||{},redux.field_objects.tabbed=redux.field_objects.tabbed||{},redux.field_objects.tabbed.getOptName=function(e){var d=e.parents().find(".redux-ajax-security").data("opt-name");return void 0===(d=void 0===d?e.parents(".redux-container").data("opt-name"):d)?redux:redux.optName},redux.field_objects.tabbed.init=function(e){e=i.redux.getSelector(e,"tabbed"),i(e).each(function(){var a=i(this),e=a;(e=a.hasClass("redux-field-container")?e:a.parents(".redux-field-container:first")).is(":hidden")||e.hasClass("redux-field-init")&&(e.removeClass("redux-field-init"),n=redux.field_objects.tabbed.getOptName(a),a.find(".redux-tabbed").each(function(){var e=a,d=e.find(".redux-tabbed-nav a"),t=e.find(".redux-tabbed-content");i.redux.initFields(),d.on("click",function(e){e.preventDefault();var e=i(this),d=e.index(),d=t.eq(d);e.addClass("redux-tabbed-active").siblings().removeClass("redux-tabbed-active"),d.removeClass("hidden").siblings().addClass("hidden"),i.redux.initFields()})}))})},redux.field_objects.tabbed.check_parents_dependencies=function(a){var r="";return n.required_child.hasOwnProperty(a)?i.each(n.required_child[a],function(e,d){var t;return(t=i("#"+n.args.opt_name+"-"+d.parent)).hasClass("hide")?r=!1:!1!==r?(null!==(t=t.serializeForm())&&"object"==typeof t&&t.hasOwnProperty(n.args.opt_name)&&(t=(void 0===t[n.args.opt_name][d.parent]?Object.values(t[n.args.opt_name])[0]:t[n.args.opt_name])[d.parent]),t=t=i("#"+n.args.opt_name+"-"+a).hasClass("redux-container-media")?t.url:t,r=i.redux.check_dependencies_visibility(t,d),!1):void 0}):r=!0,r}}(jQuery);

View File

@@ -0,0 +1,72 @@
.redux-container-tabbed {
.redux-tabbed-content {
border: 1px solid #ccd0d4;
background-color: #fff;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
}
.redux-tabbed-content > .redux-tab-field {
padding: 15px;
&.hide {
display: none;
}
}
.redux-tabbed-nav .redux-tab-icon {
padding-right: 5px;
}
.redux-tabbed-nav a {
display: inline-block;
padding: 12px 15px;
margin-top: 1px;
margin-right: 5px;
margin-bottom: -1px;
position: relative;
text-decoration: none;
color: #444;
font-weight: 600;
border: 1px solid #ccd0d4;
background-color: #f3f3f3;
transition: all .2s;
}
.redux-tabbed-nav a:hover {
background-color: #f9f9f9;
}
.redux-tabbed-nav a.redux-tabbed-active {
background-color: #fff;
border-bottom-color: #fff;
}
.redux-tabbed-nav a:focus {
outline: none;
box-shadow: none;
}
.redux-tab-field + .redux-tab-field {
border-top: 1px solid #eee;
}
.redux-field-title {
position: relative;
width: 20%;
float: left;
h4 {
margin-bottom: 0;
}
}
.redux-field-subtitle {
margin-top: 6px;
font-weight: 400;
color: #999;
}
.description {
color: #999;
}
}