Compare commits
2 Commits
f58248a8e7
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| c85761857a | |||
| 2b91c368ee |
@@ -24,9 +24,9 @@ class Partnerexpo_Core_User_Fields extends Partnerexpo_Core {
|
|||||||
$this->loader->add_action( 'personal_options_update', $this, 'save_custom_user_fields' );
|
$this->loader->add_action( 'personal_options_update', $this, 'save_custom_user_fields' );
|
||||||
$this->loader->add_action( 'edit_user_profile_update', $this, 'save_custom_user_fields' );
|
$this->loader->add_action( 'edit_user_profile_update', $this, 'save_custom_user_fields' );
|
||||||
$this->loader->add_action( 'user_register', $this, 'add_value_after_reg' );
|
$this->loader->add_action( 'user_register', $this, 'add_value_after_reg' );
|
||||||
$this->loader->add_action( 'register_form', $this, 'registration_form' );
|
|
||||||
$this->loader->add_filter( 'registration_errors', $this, 'registration_errors', 10, 3 );
|
$this->loader->add_filter( 'registration_errors', $this, 'registration_errors', 10, 3 );
|
||||||
$this->loader->add_filter( 'comment_post', $this, 'validate_comment' );
|
$this->loader->add_filter( 'comment_post', $this, 'validate_comment' );
|
||||||
|
$this->loader->add_filter( 'wp_authenticate_user', $this, 'check_status', 30, 3 );
|
||||||
|
|
||||||
$this->loader->add_action( 'init', $this, 'remove_filters' );
|
$this->loader->add_action( 'init', $this, 'remove_filters' );
|
||||||
|
|
||||||
@@ -79,7 +79,12 @@ class Partnerexpo_Core_User_Fields extends Partnerexpo_Core {
|
|||||||
|
|
||||||
|
|
||||||
public function add_custom_user_fields( $user ) {
|
public function add_custom_user_fields( $user ) {
|
||||||
|
if( ! current_user_can( 'pexpo_manage_users' ) ) { // Custom capability, added with external plugin
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$company = get_user_meta( $user->ID, 'company', true );
|
$company = get_user_meta( $user->ID, 'company', true );
|
||||||
|
$user_status = get_user_meta( $user->ID, 'user_status', true );
|
||||||
$logo_id = get_user_meta( $user->ID, 'company_logo_attachment_id', true );
|
$logo_id = get_user_meta( $user->ID, 'company_logo_attachment_id', true );
|
||||||
$logo_url = $logo_id ? wp_get_attachment_url( $logo_id ) : '';
|
$logo_url = $logo_id ? wp_get_attachment_url( $logo_id ) : '';
|
||||||
wp_enqueue_media();
|
wp_enqueue_media();
|
||||||
@@ -102,6 +107,15 @@ class Partnerexpo_Core_User_Fields extends Partnerexpo_Core {
|
|||||||
<input type="text" name="company" id="company" value="<?php echo esc_attr( $company ) ?>" class="regular-text" />
|
<input type="text" name="company" id="company" value="<?php echo esc_attr( $company ) ?>" class="regular-text" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th><label for="user_status"><?php _e( 'Státusz', 'partnerexpo-core' ) ?></label></th>
|
||||||
|
<td>
|
||||||
|
<select name="user_status" id="user_status" class="regular-text">
|
||||||
|
<option value="active" <?php selected( $user_status, 'active' ); ?>><?php _e( 'Aktív', 'partnerexpo-core' ); ?></option>
|
||||||
|
<option value="inactive" <?php selected( $user_status, 'inactive' ); ?>><?php _e( 'Inaktív', 'partnerexpo-core' ); ?></option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
@@ -115,13 +129,18 @@ class Partnerexpo_Core_User_Fields extends Partnerexpo_Core {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( isset($_POST['company']) ) {
|
$expected_fields = [
|
||||||
update_user_meta(
|
|
||||||
$user_id,
|
|
||||||
'company',
|
'company',
|
||||||
sanitize_text_field($_POST['company'])
|
'user_status',
|
||||||
);
|
];
|
||||||
|
|
||||||
|
foreach ( $expected_fields as $field ) {
|
||||||
|
if ( ! empty( $_POST[ $field ] ) ) {
|
||||||
|
$sanitized_value = sanitize_text_field( wp_unslash( $_POST[ $field ] ) );
|
||||||
|
update_user_meta( $user_id, $field, $sanitized_value );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( isset($_POST['image_attachment_id']) ) {
|
if ( isset($_POST['image_attachment_id']) ) {
|
||||||
update_user_meta(
|
update_user_meta(
|
||||||
$user_id,
|
$user_id,
|
||||||
@@ -132,31 +151,51 @@ class Partnerexpo_Core_User_Fields extends Partnerexpo_Core {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function add_value_after_reg( $user_id ) {
|
public function add_value_after_reg( $user_id ) {
|
||||||
|
$expected_fields = [
|
||||||
if ( ! empty( $_POST['company'] ) ) {
|
'last_name',
|
||||||
update_user_meta(
|
'first_name',
|
||||||
$user_id,
|
'phone',
|
||||||
'company',
|
'company',
|
||||||
sanitize_text_field( $_POST['company'] )
|
'recommended',
|
||||||
);
|
'newsletter',
|
||||||
}
|
'gdpr',
|
||||||
|
];
|
||||||
|
|
||||||
if ( ! empty( $_POST['image_attachment_id'] ) ) {
|
foreach ( $expected_fields as $field ) {
|
||||||
update_user_meta(
|
if ( ! empty( $_POST[ $field ] ) ) {
|
||||||
$user_id,
|
$sanitized_value = sanitize_text_field( wp_unslash( $_POST[ $field ] ) );
|
||||||
'company_logo_attachment_id',
|
update_user_meta( $user_id, $field, $sanitized_value );
|
||||||
absint( $_POST['image_attachment_id'] )
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function registration_form() {
|
if ( ! empty( $_FILES['business_logo']['name'] ) ) {
|
||||||
?>
|
|
||||||
<p>
|
require_once( ABSPATH . 'wp-admin/includes/image.php' );
|
||||||
<label for="company"><?php _e( 'Cég neve', 'partnerexpo-core' ) ?><br />
|
require_once( ABSPATH . 'wp-admin/includes/file.php' );
|
||||||
<input type="text" name="company" id="company" class="input" value="" size="25" /></label>
|
require_once( ABSPATH . 'wp-admin/includes/media.php' );
|
||||||
</p>
|
|
||||||
<?php
|
$attachment_id = media_handle_upload( 'business_logo', 0 );
|
||||||
|
|
||||||
|
if ( ! is_wp_error( $attachment_id ) ) {
|
||||||
|
update_user_meta( $user_id, 'company_logo_attachment_id', $attachment_id );
|
||||||
|
} else {
|
||||||
|
Logger::log( sprintf( __( 'Kép feltöltése sikertelen: %s', 'partnerexpo-core' ), $attachment_id->get_error_message() ), ['user_id' => $user_id] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Set the default user status
|
||||||
|
update_user_meta( $user_id, 'user_status', 'inactive' );
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_status( WP_User $user ) {
|
||||||
|
|
||||||
|
$status = get_user_meta( $user->ID, 'user_status' );
|
||||||
|
|
||||||
|
if ($status && is_array($status) && isset($status[0]) && $status[0] === 'inactive') {
|
||||||
|
return new WP_Error( 'authentication_failed', __( 'A fiókod még nem aktív. Kérlek, várj türelemmel, amíg ellenőrizzük a regisztrációdat.', 'partnerexpo-core' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
function registration_errors( $errors, $sanitized_user_login, $user_email ) {
|
function registration_errors( $errors, $sanitized_user_login, $user_email ) {
|
||||||
|
|||||||
@@ -37,8 +37,6 @@ class Partnerexpo_Core_Integration_Comment_Form {
|
|||||||
$newsletter_value = 1;
|
$newsletter_value = 1;
|
||||||
# # # # #
|
# # # # #
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
|
||||||
if ( ! $this->client ) {
|
if ( ! $this->client ) {
|
||||||
Logger::log(__("MiniCRM Kliens nem található, Szinkronizálás megszakítása!", 'partnerexpo-core'), [$com_id_text => $comment_id]);
|
Logger::log(__("MiniCRM Kliens nem található, Szinkronizálás megszakítása!", 'partnerexpo-core'), [$com_id_text => $comment_id]);
|
||||||
return;
|
return;
|
||||||
@@ -70,7 +68,7 @@ class Partnerexpo_Core_Integration_Comment_Form {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$user_exists = $this->client->get('Contact', ['Email' => $data['email']]);
|
$user_exists = $this->client->get('Contact', ['Email' => $data['email'], 'Deleted' => 0]);
|
||||||
if ( ! is_array($user_exists) ) {
|
if ( ! is_array($user_exists) ) {
|
||||||
Logger::log(__("Kontakt létezésének lekérése sikertelen!", "partnerexpo-core"), [$com_id_text => $comment_id, 'email' => $data['email'], $error_text => $this->client->getLastError()]);
|
Logger::log(__("Kontakt létezésének lekérése sikertelen!", "partnerexpo-core"), [$com_id_text => $comment_id, 'email' => $data['email'], $error_text => $this->client->getLastError()]);
|
||||||
return;
|
return;
|
||||||
@@ -78,6 +76,7 @@ class Partnerexpo_Core_Integration_Comment_Form {
|
|||||||
|
|
||||||
$user_id = 0;
|
$user_id = 0;
|
||||||
$has_company = true;
|
$has_company = true;
|
||||||
|
$comp_id = 0;
|
||||||
|
|
||||||
if ($user_exists['Count'] == 0) {
|
if ($user_exists['Count'] == 0) {
|
||||||
$new_contact = $this->client->put('Contact', [
|
$new_contact = $this->client->put('Contact', [
|
||||||
@@ -96,14 +95,16 @@ class Partnerexpo_Core_Integration_Comment_Form {
|
|||||||
} else {
|
} else {
|
||||||
$user_id = array_key_first($user_exists['Results']);
|
$user_id = array_key_first($user_exists['Results']);
|
||||||
$existing_contact = $this->client->get('Contact/'.$user_id);
|
$existing_contact = $this->client->get('Contact/'.$user_id);
|
||||||
if ( ! is_array($existing_contact) || ! isset($existing_contact['id']) ) {
|
if ( ! is_array($existing_contact) || ! isset($existing_contact['Id']) ) {
|
||||||
Logger::log(__("Kontakt adatok lekérése sikertelen!", "partnerexpo-core"), [$com_id_text => $comment_id, 'contact_id' => $user_id, $error_text => $this->client->getLastError()]);
|
Logger::log(__("Kontakt adatok lekérése sikertelen!", "partnerexpo-core"), [$com_id_text => $comment_id, 'contact_id' => $user_id, $error_text => $this->client->getLastError()]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($existing_contact['BusinessId']) || empty($existing_contact['BusinessId'])) {
|
if (!isset($existing_contact['BusinessId']) || empty($existing_contact['BusinessId'])) {
|
||||||
$has_company = false;
|
$has_company = false;
|
||||||
|
} else {
|
||||||
|
$comp_id = $existing_contact['BusinessId'];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! $user_id ) {
|
if ( ! $user_id ) {
|
||||||
@@ -112,14 +113,12 @@ class Partnerexpo_Core_Integration_Comment_Form {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( ! $has_company ) {
|
if ( ! $has_company ) {
|
||||||
$comp_exists = $this->client->get('Contact', ['Name' => $data['company'], 'Type' => 'Business']);
|
$comp_exists = $this->client->get('Contact', ['Name' => $data['company'], 'Type' => 'Business', 'Deleted' => 0]);
|
||||||
if ( ! is_array($user_exists) ) {
|
if ( ! is_array($comp_exists.,.) ) {
|
||||||
Logger::log(__("Kontakt létezésének lekérése sikertelen!", "partnerexpo-core"), [$com_id_text => $comment_id, 'email' => $data['email'], $error_text => $this->client->getLastError()]);
|
Logger::log(__("Kontakt létezésének lekérése sikertelen!", "partnerexpo-core"), [$com_id_text => $comment_id, 'email' => $data['email'], $error_text => $this->client->getLastError()]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$comp_id = 0;
|
|
||||||
|
|
||||||
if ($comp_exists['Count'] == 0) {
|
if ($comp_exists['Count'] == 0) {
|
||||||
$new_comp = $this->client->put('Contact', [
|
$new_comp = $this->client->put('Contact', [
|
||||||
'Name' => $data['company'],
|
'Name' => $data['company'],
|
||||||
@@ -145,7 +144,8 @@ class Partnerexpo_Core_Integration_Comment_Form {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$card_exists = $this->client->get('Project', ['CategoryId' => $category_id, 'ContactId' => $user_id]);
|
|
||||||
|
$card_exists = $this->client->get('Project', ['CategoryId' => $category_id, 'ContactId' => $user_id, 'Deleted' => 0]);
|
||||||
if ( ! is_array($card_exists) ) {
|
if ( ! is_array($card_exists) ) {
|
||||||
Logger::log(__("Adatlap adatok lekérése sikertelen:", "partnerexpo-core"), [$com_id_text => $comment_id, 'contact_id' => $user_id, $error_text => $this->client->getLastError()]);
|
Logger::log(__("Adatlap adatok lekérése sikertelen:", "partnerexpo-core"), [$com_id_text => $comment_id, 'contact_id' => $user_id, $error_text => $this->client->getLastError()]);
|
||||||
return;
|
return;
|
||||||
@@ -195,6 +195,7 @@ class Partnerexpo_Core_Integration_Comment_Form {
|
|||||||
Logger::log(__("Teendő létrehozása sikertelen létező adatlap esetén!", "partnerexpo-core"), [$com_id_text => $comment_id, 'project_id' => $card_id, $error_text => $this->client->getLastError()]);
|
Logger::log(__("Teendő létrehozása sikertelen létező adatlap esetén!", "partnerexpo-core"), [$com_id_text => $comment_id, 'project_id' => $card_id, $error_text => $this->client->getLastError()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch ( Exception $e ) {
|
} catch ( Exception $e ) {
|
||||||
Logger::log(__("Ismeretlen hiba történt a szinkronizálás során!", "partnerexpo-core"), [$com_id_text => $comment_id, 'exception' => $e->getMessage()]);
|
Logger::log(__("Ismeretlen hiba történt a szinkronizálás során!", "partnerexpo-core"), [$com_id_text => $comment_id, 'exception' => $e->getMessage()]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
* Plugin Name: PartnerExpo Core
|
* Plugin Name: PartnerExpo Core
|
||||||
* Plugin URI: https://partnerexpo.eu
|
* Plugin URI: https://partnerexpo.eu
|
||||||
* Description: A PartnerEXPO oldal belső pluginja
|
* Description: A PartnerEXPO oldal belső pluginja
|
||||||
* Version: 1.1.12
|
* Version: 1.1.16
|
||||||
* Author: Juhász Levente
|
* Author: Juhász Levente
|
||||||
* Author URI: https://github.com/Duskell/
|
* Author URI: https://github.com/Duskell/
|
||||||
* License: GPL-2.0+
|
* License: GPL-2.0+
|
||||||
@@ -23,7 +23,7 @@ if ( ! defined( 'WPINC' ) ) {
|
|||||||
die;
|
die;
|
||||||
}
|
}
|
||||||
|
|
||||||
define( 'PARTNEREXPO_CORE_VERSION', '1.1.12' );
|
define( 'PARTNEREXPO_CORE_VERSION', '1.1.16' );
|
||||||
|
|
||||||
function activate_partnerexpo_core() {
|
function activate_partnerexpo_core() {
|
||||||
require_once plugin_dir_path( __FILE__ ) . 'includes/class-partnerexpo-core-activator.php';
|
require_once plugin_dir_path( __FILE__ ) . 'includes/class-partnerexpo-core-activator.php';
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ class Partnerexpo_Core_Public {
|
|||||||
add_shortcode( 'partnerexpo_searchbox', [ $this, 'searchbox_shortcode' ] );
|
add_shortcode( 'partnerexpo_searchbox', [ $this, 'searchbox_shortcode' ] );
|
||||||
add_shortcode( 'partnerexpo_comment_section', [ $this, 'comments_shortcode' ] );
|
add_shortcode( 'partnerexpo_comment_section', [ $this, 'comments_shortcode' ] );
|
||||||
add_shortcode( 'partnerexpo_company_head', [ $this, 'company_head_shortcode' ] );
|
add_shortcode( 'partnerexpo_company_head', [ $this, 'company_head_shortcode' ] );
|
||||||
|
add_shortcode( 'partnerexpo_register', [ $this, 'register_shortcode' ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function searchbox_shortcode() {
|
public function searchbox_shortcode() {
|
||||||
@@ -74,6 +75,23 @@ class Partnerexpo_Core_Public {
|
|||||||
return ob_get_clean();
|
return ob_get_clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function register_shortcode($atts) {
|
||||||
|
wp_enqueue_style( $this->plugin_name . '-register-css' );
|
||||||
|
|
||||||
|
wp_enqueue_script( $this->plugin_name . '-register-js' );
|
||||||
|
|
||||||
|
$atts = shortcode_atts( array(
|
||||||
|
'post_id' => get_the_ID(),
|
||||||
|
), $atts );
|
||||||
|
|
||||||
|
// // This variable is now scoped and ready for the partial
|
||||||
|
// $post_id = intval( $atts['post_id'] );
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
include plugin_dir_path( __FILE__ ) . 'partials/partnerexpo-core-public-register.php';
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
public function company_head_shortcode() {
|
public function company_head_shortcode() {
|
||||||
wp_enqueue_style( $this->plugin_name . '-company-head-css' );
|
wp_enqueue_style( $this->plugin_name . '-company-head-css' );
|
||||||
|
|
||||||
@@ -216,6 +234,14 @@ class Partnerexpo_Core_Public {
|
|||||||
'all'
|
'all'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
wp_register_style(
|
||||||
|
$this->plugin_name . '-register-css',
|
||||||
|
plugin_dir_url( __FILE__ ) . 'css/register.css',
|
||||||
|
[],
|
||||||
|
$this->version,
|
||||||
|
'all'
|
||||||
|
);
|
||||||
|
|
||||||
wp_register_style(
|
wp_register_style(
|
||||||
$this->plugin_name . '-multiselect-css',
|
$this->plugin_name . '-multiselect-css',
|
||||||
plugin_dir_url( __FILE__ ) . 'css/multiselect.css',
|
plugin_dir_url( __FILE__ ) . 'css/multiselect.css',
|
||||||
@@ -247,15 +273,6 @@ class Partnerexpo_Core_Public {
|
|||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
wp_register_script(
|
|
||||||
$this->plugin_name . '-comments-js',
|
|
||||||
plugin_dir_url( __FILE__ ) . 'js/comments.js',
|
|
||||||
[],
|
|
||||||
$this->version,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
wp_register_script(
|
wp_register_script(
|
||||||
$this->plugin_name . '-multiselect-js',
|
$this->plugin_name . '-multiselect-js',
|
||||||
plugin_dir_url( __FILE__ ) . 'js/multiselect.js',
|
plugin_dir_url( __FILE__ ) . 'js/multiselect.js',
|
||||||
@@ -264,7 +281,6 @@ class Partnerexpo_Core_Public {
|
|||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
wp_register_script(
|
wp_register_script(
|
||||||
$this->plugin_name . '-comments-js',
|
$this->plugin_name . '-comments-js',
|
||||||
plugin_dir_url( __FILE__ ) . 'js/comments.js',
|
plugin_dir_url( __FILE__ ) . 'js/comments.js',
|
||||||
@@ -272,6 +288,14 @@ class Partnerexpo_Core_Public {
|
|||||||
$this->version,
|
$this->version,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
|
wp_register_script(
|
||||||
|
$this->plugin_name . '-register-js',
|
||||||
|
plugin_dir_url( __FILE__ ) . 'js/register.js',
|
||||||
|
[ 'jquery' ],
|
||||||
|
$this->version,
|
||||||
|
true
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -45,13 +45,14 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
width: max-content;
|
width: max-content;
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
animation: scrolling 20s linear infinite;
|
animation: scrolling 5s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.pexpo-core-comment-group {
|
.pexpo-core-comment-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 100px;
|
gap: 100px;
|
||||||
|
padding-right: 100px;
|
||||||
width: max-content;
|
width: max-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +111,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 500px;
|
max-width: 600px;
|
||||||
box-shadow: #00000020 0px 5px 20px 0;
|
box-shadow: #00000020 0px 5px 20px 0;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
@@ -199,6 +200,6 @@
|
|||||||
|
|
||||||
@keyframes scrolling {
|
@keyframes scrolling {
|
||||||
to {
|
to {
|
||||||
transform: translate3d(-50%, 0, 0);
|
transform: translate3d(calc(-100% / var(--group-count)), 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
240
public/css/register.css
Normal file
240
public/css/register.css
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
#pexpo-custom-comment-form {
|
||||||
|
width: 100%;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pexpo-core-comments-title {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 2rem;
|
||||||
|
color: #333;
|
||||||
|
margin-top: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pexpo-core-comments-body:has(> .pexpo-core-comment-groups-wrapper) {
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px 0;
|
||||||
|
max-width: 1500px;
|
||||||
|
overflow: hidden;
|
||||||
|
-webkit-mask-image: linear-gradient(
|
||||||
|
to right,
|
||||||
|
transparent,
|
||||||
|
black 80px,
|
||||||
|
black calc(100% - 80px),
|
||||||
|
transparent
|
||||||
|
);
|
||||||
|
|
||||||
|
mask-image: linear-gradient(
|
||||||
|
to right,
|
||||||
|
transparent,
|
||||||
|
black 80px,
|
||||||
|
black calc(100% - 80px),
|
||||||
|
transparent
|
||||||
|
);
|
||||||
|
|
||||||
|
&:hover .pexpo-core-comment-groups-wrapper {
|
||||||
|
animation-play-state: paused;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pexpo-core-comment-groups-wrapper {
|
||||||
|
display: flex;
|
||||||
|
width: max-content;
|
||||||
|
will-change: transform;
|
||||||
|
animation: scrolling 20s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.pexpo-core-comment-group {
|
||||||
|
display: flex;
|
||||||
|
gap: 100px;
|
||||||
|
width: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pexpo-core-comment {
|
||||||
|
position: relative;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 500px;
|
||||||
|
color: #333;
|
||||||
|
border-radius: 24px;
|
||||||
|
box-shadow: rgba(0,0,0,0.1) 5px 5px 20px 0;
|
||||||
|
padding: 20px 20px 50px 20px;
|
||||||
|
min-height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pexpo-core-comment-content {
|
||||||
|
font-style: italic;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
max-height: 250px;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
margin-bottom: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pexpo-core-comment-said_by {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 20px;
|
||||||
|
right: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #555;
|
||||||
|
padding-left: 30px;
|
||||||
|
max-height: 50px;
|
||||||
|
|
||||||
|
& p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.comment-form:has(> .pexpo-core-com-form-wrapper) {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-top: 100px;
|
||||||
|
|
||||||
|
& .form-submit .submit {
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pexpo-core-com-form-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 500px;
|
||||||
|
box-shadow: #00000020 0px 5px 20px 0;
|
||||||
|
border-radius: 15px;
|
||||||
|
padding: 20px;
|
||||||
|
margin-top: 50px;
|
||||||
|
|
||||||
|
& .pexpo-core-com-form-title {
|
||||||
|
margin: 0 0 20px 0;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
color: #333;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .pexpo-core-com-field {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 5px;
|
||||||
|
|
||||||
|
& label {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
& input, & textarea {
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: none;
|
||||||
|
background-color: #00000010;
|
||||||
|
font-size: 1rem;
|
||||||
|
resize: vertical;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
background-color: #00000020;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pexpo-core-com-consent {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
justify-content: left;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
|
||||||
|
& div {
|
||||||
|
display: flex;
|
||||||
|
gap: 5px;
|
||||||
|
|
||||||
|
& input[type="checkbox"] {
|
||||||
|
width: auto;
|
||||||
|
transform: scale(1.2);
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pexpo-core-no-comments {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: #777;
|
||||||
|
margin: 50px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pexpo-core-submit-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 40px;
|
||||||
|
|
||||||
|
& .submit {
|
||||||
|
background-image: linear-gradient(rgb(178, 34, 34) 21%, rgb(149, 0, 0) 87%);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 15px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
font-size: 1rem;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.pexpo-core-image-drop-zone {
|
||||||
|
position: relative;
|
||||||
|
border: 2px dashed #ccc;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 40px 20px;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pexpo-core-image-drop-zone:hover,
|
||||||
|
.pexpo-core-image-drop-zone.is-dragover {
|
||||||
|
background-color: #e1f5fe;
|
||||||
|
border-color: #03a9f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pexpo-core-image-drop-zone input[type="file"] {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
opacity: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pexpo-core-image-preview {
|
||||||
|
max-width: 200px;
|
||||||
|
display: none;
|
||||||
|
margin: 20px auto 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes scrolling {
|
||||||
|
to {
|
||||||
|
transform: translate3d(-50%, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
41
public/js/register.js
Normal file
41
public/js/register.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
jQuery( document ).ready( function( $ ) {
|
||||||
|
|
||||||
|
var $dropZone = $('#pexpo-core-image-drop-zone');
|
||||||
|
var $fileInput = $('#pexpo-core-image-logo');
|
||||||
|
var $preview = $('#pexpo-core-image-preview');
|
||||||
|
var $dropText = $dropZone.find('.pexpo-core-image-drop-text');
|
||||||
|
|
||||||
|
// Add a class when a file is dragged over the box
|
||||||
|
$dropZone.on('dragover dragenter', function() {
|
||||||
|
$dropZone.addClass('is-dragover');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Remove the class when the file leaves or is dropped
|
||||||
|
$dropZone.on('dragleave dragend drop', function() {
|
||||||
|
$dropZone.removeClass('is-dragover');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle the file selection (Click or Drop)
|
||||||
|
$fileInput.on('change', function( event ) {
|
||||||
|
var file = event.target.files[0];
|
||||||
|
|
||||||
|
if ( file ) {
|
||||||
|
var reader = new FileReader();
|
||||||
|
|
||||||
|
reader.onload = function( e ) {
|
||||||
|
// Show the image preview
|
||||||
|
$preview.attr('src', e.target.result).css('display', 'block');
|
||||||
|
|
||||||
|
// Optional: Change the text inside the box
|
||||||
|
$dropText.text('Kép kiválasztva. Kattintson vagy húzzon ide egy újat a cseréhez.');
|
||||||
|
};
|
||||||
|
|
||||||
|
reader.readAsDataURL( file );
|
||||||
|
} else {
|
||||||
|
// Reset if user cancels
|
||||||
|
$preview.hide().attr('src', '');
|
||||||
|
$dropText.text('Húzza ide a képet, vagy kattintson a tallózáshoz');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
@@ -26,12 +26,12 @@ $complience_url = "rendszerepito.hu/adatkezeles";
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
if ( ! empty( $comments ) ) {
|
if ( ! empty( $comments ) ) {
|
||||||
echo '<div class="pexpo-core-comment-groups-wrapper">';
|
|
||||||
if ( count( $comments ) < 3 ) {
|
if ( count( $comments ) < 3 ) {
|
||||||
$groups = 6 / count( $comments );
|
$groups = 4 / count( $comments );
|
||||||
} else {
|
} else {
|
||||||
$groups = 2;
|
$groups = 2;
|
||||||
}
|
}
|
||||||
|
echo '<div class="pexpo-core-comment-groups-wrapper" style="--group-count: ' . esc_attr( $groups ) . ';">';
|
||||||
for ($i = 0; $i < $groups; $i++) {
|
for ($i = 0; $i < $groups; $i++) {
|
||||||
echo '<div class="pexpo-core-comment-group"'.($i ? ' aria-hidden="true"' : '').'>';
|
echo '<div class="pexpo-core-comment-group"'.($i ? ' aria-hidden="true"' : '').'>';
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ $complience_url = "rendszerepito.hu/adatkezeles";
|
|||||||
|
|
||||||
<p class="pexpo-core-com-field">
|
<p class="pexpo-core-com-field">
|
||||||
<label for="mail"><?php echo esc_html_x( 'Email cím', 'partnerexpo_core' ); ?></label><br />
|
<label for="mail"><?php echo esc_html_x( 'Email cím', 'partnerexpo_core' ); ?></label><br />
|
||||||
<input type="mail" id="mail" name="mail" aria-required="true" required>
|
<input type="email" id="mail" name="mail" aria-required="true" required>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class="pexpo-core-com-field">
|
<p class="pexpo-core-com-field">
|
||||||
|
|||||||
77
public/partials/partnerexpo-core-public-register.php
Normal file
77
public/partials/partnerexpo-core-public-register.php
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the code for the comments shortcode
|
||||||
|
*
|
||||||
|
* @link https://github.com/Duskell
|
||||||
|
* @since 1.1.4
|
||||||
|
*
|
||||||
|
* @package Partnerexpo_Core
|
||||||
|
* @subpackage Partnerexpo_Core/public/partials
|
||||||
|
*/
|
||||||
|
|
||||||
|
$complience_url = "rendszerepito.hu/adatkezeles";
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="pexpo-core-comments" id="pexpo-core-comments">
|
||||||
|
<form action="<?php echo site_url( '/wp-login.php?action=register' ); ?>" method="post" id="pexpo-custom-comment-form" enctype="multipart/form-data">
|
||||||
|
<div class="pexpo-core-com-form-wrapper">
|
||||||
|
<h2 class="pexpo-core-com-form-title"><?php echo esc_html_x( 'Regisztráció', 'partnerexpo_core' ); ?></h2>
|
||||||
|
<p class="pexpo-core-com-field">
|
||||||
|
<label for="user_login"><?php echo esc_html_x( 'Felhasználónév', 'partnerexpo_core' ); ?></label><br />
|
||||||
|
<input type="text" id="user_login" name="user_login" aria-required="true" required>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="pexpo-core-com-field">
|
||||||
|
<label for="user_email"><?php echo esc_html_x( 'Email cím', 'partnerexpo_core' ); ?></label><br />
|
||||||
|
<input type="email" id="user_email" name="user_email" aria-required="true" required>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="pexpo-core-com-field">
|
||||||
|
<label for="last_name"><?php echo esc_html_x( 'Vezetéknév', 'partnerexpo_core' ); ?></label><br />
|
||||||
|
<input type="text" id="last_name" name="last_name" aria-required="true" required>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="pexpo-core-com-field">
|
||||||
|
<label for="first_name"><?php echo esc_html_x( 'Keresztnév', 'partnerexpo_core' ); ?></label><br />
|
||||||
|
<input type="text" id="first_name" name="first_name" aria-required="true" required>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="pexpo-core-com-field">
|
||||||
|
<label for="phone"><?php echo esc_html_x( 'Telefonszám', 'partnerexpo_core' ); ?></label><br />
|
||||||
|
<input type="tel" id="phone" name="phone" aria-required="true" required>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="pexpo-core-com-field">
|
||||||
|
<label for="pexpo-core-image-logo"><?php echo esc_html_x( 'Céges logó', 'partnerexpo_core' ); ?></label>
|
||||||
|
|
||||||
|
<div id="pexpo-core-image-drop-zone" class="pexpo-core-image-drop-zone">
|
||||||
|
<span class="pexpo-core-image-drop-text">Húzza ide a képet, vagy kattintson a tallózáshoz</span>
|
||||||
|
|
||||||
|
<input type="file" id="pexpo-core-image-logo" name="business_logo" accept="image/png, image/jpeg, image/webp" />
|
||||||
|
|
||||||
|
<img id="pexpo-core-image-preview" src="" alt="Logo Preview" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="pexpo-core-com-field">
|
||||||
|
<label for="company"><?php echo esc_html_x( 'Cég név', 'partnerexpo_core' ); ?></label><br />
|
||||||
|
<input type="text" id="company" name="company" aria-required="true" required>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="pexpo-core-com-field">
|
||||||
|
<label for="recommended"><?php echo esc_html_x( 'Ajánló neve', 'partnerexpo_core' ); ?></label><br />
|
||||||
|
<input type="text" id="recommended" name="recommended" aria-required="true" required>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="pexpo-core-com-consent">
|
||||||
|
<div><input type="checkbox" id="gdpr" name="gdpr" aria-required="true" maxlength="600" required>GDPR <a href="https://<?php echo esc_url( $complience_url ) ?>"><?php echo __( $complience_url ) ?></a> - <?php echo esc_html_x( 'Elfogadom', 'partnerexpo_core' ); ?></input></div>
|
||||||
|
<div><input type="checkbox" id="newsletter" name="newsletter" aria-required="true" maxlength="600"> <?php echo esc_html_x( 'Feliratkozom a hírlevélre.', 'partnerexpo_core' ); ?></input></div></div>
|
||||||
|
|
||||||
|
<div class="pexpo-core-submit-wrapper">
|
||||||
|
<button type="submit" name="submit" id="submit" class="submit"><?php _e( 'Küldés', 'partnerexpo-core' ); ?></button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -1,529 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
||||||
<title>Mock Search UI (Masonry)</title>
|
|
||||||
<link rel="stylesheet" href="css/multiselect.css">
|
|
||||||
<style>
|
|
||||||
.pexpo-core-root { --accent1: #950000; --accent2: #2c3489; --darker: 30%; --lighter: 30%; --bg: #f6f7fb; --panel: #ffffff; --panel2: #f2f4fb; --stroke: rgba(16, 24, 40, .10); --stroke2: rgba(16, 24, 40, .14); --text: rgba(16, 24, 40, .92); --muted: rgba(16, 24, 40, .62); --shadow: 0 18px 45px rgba(16,24,40,.12); --r: 14px; --cardMin: 240; --gap: 12px; --filterW: 170px; --filterWOpen: 360px; --toggle-bg-off: #ca0000; --toggle-bg-on: #10bb2d; --toggle-nub-color: #f6f7fb; --topbarH: 64px; font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji","Segoe UI Emoji"; color: var(--text); line-height: 1.35; font-size: 14px; }
|
|
||||||
.pexpo-core-root * { box-sizing: border-box; }
|
|
||||||
.pexpo-core-shell { width: min(1100px, 96vw); height: min(720px, 92vh); background: linear-gradient(180deg, rgba(44,52,137,.05), transparent 42%), var(--panel); border: 1px solid var(--stroke); border-radius: calc(var(--r) + 2px); box-shadow: var(--shadow); overflow: hidden; display:flex; flex-direction:column; position: relative; isolation: isolate; }
|
|
||||||
.pexpo-core-topbar { display:flex; align-items:flex-start; justify-content:space-between; gap: 12px; padding: 14px; border-bottom: 1px solid var(--stroke); background: linear-gradient(180deg, rgba(16,24,40,.02), rgba(16,24,40,.00)); position: relative; z-index: 3; }
|
|
||||||
.pexpo-core-topHeight { height: 45px; }
|
|
||||||
.pexpo-core-filterWrap { width: var(--filterW); transition: width 220ms ease; }
|
|
||||||
.pexpo-core-filterWrap.pexpo-core-open { width: var(--filterWOpen); }
|
|
||||||
.pexpo-core-filterBtn { width: 100%; display:flex; align-items:center; justify-content:space-between; gap: 10px; padding: 10px 10px; border-radius: 12px; border: 1px solid var(--stroke2); background: var(--panel2); color: var(--text); cursor:pointer; user-select:none; box-shadow: 0 8px 22px rgba(16,24,40,.10); }
|
|
||||||
.pexpo-core-filterBtn .pexpo-core-left { display:flex; align-items:center; gap: 10px; min-width: 0; }
|
|
||||||
.pexpo-core-pill { font-size: 12px; padding: 3px 8px; border: 1px solid rgba(44,52,137,.25); border-radius: 999px; color: rgba(44,52,137,.85); background: rgba(44,52,137,.06); white-space:nowrap; }
|
|
||||||
.pexpo-core-filterBtn .pexpo-core-label { font-weight: 650; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
||||||
.pexpo-core-sortWrap { display:flex; justify-content: space-between; align-items:center; gap: 10px; padding: 10px 10px; border-radius: 12px; border: 1px solid var(--stroke2); background: var(--panel2); color: var(--text); box-shadow: 0 8px 22px rgba(16,24,40,.10); flex: 0 0 auto; }
|
|
||||||
.pexpo-core-sortLabel { font-weight: 650; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
||||||
.pexpo-core-sortSelect { border: 1px solid rgba(16,24,40,.16); background: rgba(255,255,255,.95); color: var(--text); border-radius: 10px; padding: 5px 10px; outline: none; font: inherit; height: 35px; }
|
|
||||||
.pexpo-core-sortSelect:focus { border-color: rgba(44,52,137,.45); box-shadow: 0 0 0 3px rgba(44,52,137,.14); }
|
|
||||||
.pexpo-core-searchWrap { flex: 1 1 auto; display:flex; justify-content:flex-end; align-items:flex-start; }
|
|
||||||
.pexpo-core-search { width: min(520px, 100%); display:flex; align-items:center; gap: 10px; padding: 10px 12px; border-radius: 14px; border: 1px solid var(--stroke2); background: rgba(255,255,255,.9); box-shadow: 0 8px 22px rgba(16,24,40,.10); }
|
|
||||||
.pexpo-core-search input { width: 100%; border: none; outline: none; background: transparent; color: var(--text); font-size: 14px; }
|
|
||||||
.pexpo-core-body { flex: 1 1 auto; padding: 14px; overflow:auto; position: relative; z-index: 1; }
|
|
||||||
.pexpo-core-metaRow { display:flex; align-items:center; justify-content:space-between; gap: 10px; margin-bottom: 12px; color: var(--muted); font-size: 12px; }
|
|
||||||
.pexpo-core-masonry { display:flex; gap: var(--gap); align-items:flex-start; }
|
|
||||||
.pexpo-core-mCol { flex: 1 1 0; min-width: 0; display:flex; flex-direction:column; gap: var(--gap); }
|
|
||||||
.pexpo-core-card { border-radius: 14px; border: 1px solid var(--stroke2); background: linear-gradient(180deg, rgba(143, 152, 255, 0.05), rgba(255,255,255,.92)); padding: 12px; box-shadow: 0 12px 26px rgba(16,24,40,.10); display:flex; flex-direction:column; gap: 8px; }
|
|
||||||
.pexpo-core-imageWrap { width: 100%; height: auto; border-radius: 10px; overflow: hidden; }
|
|
||||||
.pexpo-core-imageWrap img { width: 100%; height: auto; display: block; }
|
|
||||||
.pexpo-core-cardTop { display:flex; align-items:flex-start; justify-content:space-between; gap: 10px; }
|
|
||||||
.pexpo-core-title { font-weight: 750; letter-spacing: .15px; color: var(--text); &:hover { color: initial; } }
|
|
||||||
.pexpo-core-tags { display: flex; flex-wrap: wrap; gap: 6px; row-gap: 6px; }
|
|
||||||
.pexpo-core-tag { font-size: 12px; padding: 3px 8px; border-radius: 999px; border: 1px solid #333333ce; color: var(--text); background: #99999930; white-space:nowrap; }
|
|
||||||
.pexpo-core-desc { color: rgba(16,24,40,.74); font-size: 13px; }
|
|
||||||
.pexpo-core-foot { margin-top:auto; display:flex; align-items:center; justify-content:space-between; color: rgba(16,24,40,.60); font-size: 12px; border-top: 1px dashed rgba(16,24,40,.16); padding-top: 8px; }
|
|
||||||
.pexpo-core-filterDrawerBackdrop { position:absolute; inset: var(--topbarH) 0 0 0; background: rgba(16,24,40,.20); backdrop-filter: blur(2px); opacity: 0; pointer-events: none; transition: opacity 180ms ease; z-index: 2; }
|
|
||||||
.pexpo-core-filterDrawerBackdrop.pexpo-core-show { opacity: 1; pointer-events: auto; }
|
|
||||||
.pexpo-core-filterDrawer { position:absolute; top: var(--topbarH); bottom: 0; left: 14px; width: var(--filterW); border-radius: 14px; border: 1px solid var(--stroke2); background: rgba(255,255,255,.92); overflow:hidden; box-shadow: 0 18px 45px rgba(16,24,40,.18); opacity: 0; transform: translateY(-8px); pointer-events: none; transition: opacity 200ms ease, transform 200ms ease, width 220ms ease; z-index: 3; display:flex; flex-direction:column; min-height: 0; margin: 12.5px 0 12.5px 0; }
|
|
||||||
.pexpo-core-filterDrawer.pexpo-core-open { opacity: 1; transform: translateY(0); pointer-events: auto; width: var(--filterWOpen); }
|
|
||||||
.pexpo-core-filterPanelHeader { display:flex; align-items:center; justify-content:space-between; padding: 10px 10px; border-bottom: 1px solid var(--stroke); color: rgba(16,24,40,.60); background: linear-gradient(180deg, rgba(44,52,137,.05), rgba(255,255,255,.0)); flex: 0 0 auto; }
|
|
||||||
.pexpo-core-filterPanelHeader b { color: var(--text); }
|
|
||||||
.pexpo-core-filterPanelBody { display: flex; padding: 10px; flex-direction: column; overflow:auto; min-height: 0; gap: 10px; }
|
|
||||||
.pexpo-core-toggle { width: 100%; display: flex; justify-content: space-between; align-items: center; }
|
|
||||||
.pexpo-core-toggle input[type="checkbox"] { display: none; }
|
|
||||||
.pexpo-core-toggle label { position: relative; display: block; width: 50px; height: 25px; cursor: pointer; }
|
|
||||||
.pexpo-core-toggle label::before { content: ''; display: block; width: 100%; height: 100%; border-radius: 4px; background: var(--toggle-bg-off); border: 1.5px solid color-mix(in srgb, var(--toggle-bg-off), black var(--darker)); box-sizing: border-box; transition: all 0.2s ease-in; }
|
|
||||||
.pexpo-core-toggle label::after { content: ''; display: block; height: 21px; width: 21px; border-radius: 2px; background: var(--toggle-nub-color); position: absolute; top: 2px; left: 2px; transition: all 0.2s ease-in; box-shadow: 0 2px 5px rgba(0,0,0,0.2); }
|
|
||||||
.pexpo-core-toggle input:checked + label::before { background: var(--toggle-bg-on); border: 1.5px solid color-mix(in srgb, var(--toggle-bg-on), black var(--darker)); }
|
|
||||||
.pexpo-core-toggle input:checked + label::after { left: 27px; }
|
|
||||||
.pexpo-core-shell.pexpo-core-drawerOpen .pexpo-core-body { transition: padding-left 220ms ease; }
|
|
||||||
.pexpo-core-shell:not(.pexpo-core-drawerOpen) .pexpo-core-body { transition: padding-left 220ms ease; }
|
|
||||||
.pexpo-core-icons-search { box-sizing: border-box; position: relative; display: block; transform: scale(var(--ggs, 1)); width: 16px; height: 16px; border: 2px solid; border-radius: 100%; margin-left: -4px; margin-top: -4px; }
|
|
||||||
.pexpo-core-icons-search:after { content: ""; display: block; box-sizing: border-box; position: absolute; border-radius: 3px; width: 3px; height: 8px; background: currentColor; transform: rotate(-45deg); top: 10px; left: 12px; }
|
|
||||||
.pexpo-core-icons-down { box-sizing: border-box; position: relative; display: block; transform: scale(var(--ggs, 1)); width: 22px; height: 22px; border: 2px solid transparent; border-radius: 100px; }
|
|
||||||
.pexpo-core-icons-down:after { content: ""; display: block; box-sizing: border-box; position: absolute; width: 10px; height: 10px; border-bottom: 2px solid; border-right: 2px solid; transform: rotate(45deg); transition: 1s transform ease; left: 4px; top: 2px; }
|
|
||||||
.pexpo-core-filterWrap.pexpo-core-open .pexpo-core-icons-down { transform: rotate(-135deg) translate(-1px,-1px); }
|
|
||||||
.pexpo-core-icons-options { box-sizing: border-box; position: relative; display: block; transform: scale(var(--ggs, 1)); width: 10px; height: 2px; box-shadow: -3px 4px 0 0, 3px -4px 0 0; margin: 0 10px 0 10px; }
|
|
||||||
.pexpo-core-icons-options::after, .pexpo-core-icons-options::before { content: ""; display: block; box-sizing: border-box; position: absolute; width: 8px; height: 8px; border: 2px solid; border-radius: 100%; }
|
|
||||||
.pexpo-core-icons-options::before { top: -7px; left: -4px; }
|
|
||||||
.pexpo-core-icons-options::after { bottom: -7px; right: -4px; }
|
|
||||||
@media (max-width: 720px) {
|
|
||||||
.pexpo-core-topbar { flex-direction:column; }
|
|
||||||
.pexpo-core-searchWrap { justify-content:stretch; }
|
|
||||||
.pexpo-core-search { width: 100%; }
|
|
||||||
.pexpo-core-filterWrap { width: 100%; }
|
|
||||||
.pexpo-core-filterWrap.pexpo-core-open { width: 100%; }
|
|
||||||
.pexpo-core-sortWrap { width: 100%; }
|
|
||||||
.pexpo-core-sortSelect { width: 110px; }
|
|
||||||
.pexpo-core-searchWrap { width: 100%; }
|
|
||||||
.pexpo-core-filterDrawer { left: 14px; right: 14px; width: auto; }
|
|
||||||
.pexpo-core-filterDrawer.pexpo-core-open { width: auto; }
|
|
||||||
.pexpo-core-shell.pexpo-core-drawerOpen .pexpo-core-body { padding-left: 14px; }
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
<div class="pexpo-core-root pexpo-core-shell" id="shell">
|
|
||||||
<div class="pexpo-core-topbar" id="topbar">
|
|
||||||
<div class="pexpo-core-filterWrap" id="filterWrap">
|
|
||||||
<div class="pexpo-core-filterBtn pexpo-core-topHeight" id="filterBtn" role="button" aria-expanded="false" tabindex="0">
|
|
||||||
<div class="pexpo-core-left">
|
|
||||||
<span class="pexpo-core-icons-options" aria-hidden="true"></span>
|
|
||||||
<span class="pexpo-core-label" id="filterLabel">Filterek</span>
|
|
||||||
</div>
|
|
||||||
<span class="pexpo-core-icons-down" aria-hidden="true"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="pexpo-core-sortWrap pexpo-core-topHeight">
|
|
||||||
<label class="pexpo-core-sortLabel" for="sortSelect">Rendezés</label>
|
|
||||||
<select id="sortSelect" class="pexpo-core-sortSelect">
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="pexpo-core-searchWrap pexpo-core-topHeight">
|
|
||||||
<div class="pexpo-core-search" role="search">
|
|
||||||
<span class="pexpo-core-icons-search" aria-hidden="true"></span>
|
|
||||||
<form id="qForm" action="javascript:void(0)">
|
|
||||||
<input id="q" placeholder="Keresés..." autocomplete="off" />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="pexpo-core-filterDrawerBackdrop" id="drawerBackdrop" aria-hidden="true"></div>
|
|
||||||
<div class="pexpo-core-filterDrawer pexpo-core-open" id="filterDrawer" aria-hidden="true">
|
|
||||||
<div class="pexpo-core-filterPanelHeader">
|
|
||||||
<span><b>Részletes keresés</b></span>
|
|
||||||
</div>
|
|
||||||
<div class="pexpo-core-filterPanelBody">
|
|
||||||
<div class="pexpo-core-toggle">
|
|
||||||
<span class="toggle-text">Címke kötelezése</span>
|
|
||||||
<div class="toggle-wrapper">
|
|
||||||
<input type="checkbox" id="pexpo-core-tag-toggle">
|
|
||||||
<label for="pexpo-core-tag-toggle"></label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<label for="pexpo-core-tags" style="margin-top:10px; display:block; font-weight:600;">Címkék</label>
|
|
||||||
|
|
||||||
<select id="pexpo-core-tags" data-placeholder="Opciók kiválasztása" multiple="multiple">
|
|
||||||
<option value="option1">Option 1</option>
|
|
||||||
<option value="option2">Option 2</option>
|
|
||||||
<option value="option3">Option 3</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="pexpo-core-body">
|
|
||||||
<div class="pexpo-core-metaRow">
|
|
||||||
<div id="metaLeft"><b id="count">0</b> találat</div>
|
|
||||||
<div id="metaRight">Elrendezés: <span id="layoutMeta">—</span></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="pexpo-core-masonry" id="masonry" aria-live="polite"></div>
|
|
||||||
|
|
||||||
<div id="measure" style="position:absolute; left:-9999px; top:-9999px; width:300px; visibility:hidden;"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
// ---------- DOM Elements ----------
|
|
||||||
const shell = document.getElementById("shell");
|
|
||||||
const topbar = document.getElementById("topbar");
|
|
||||||
|
|
||||||
const filterWrap = document.getElementById("filterWrap");
|
|
||||||
const filterBtn = document.getElementById("filterBtn");
|
|
||||||
const filterDrawer = document.getElementById("filterDrawer");
|
|
||||||
const drawerBackdrop = document.getElementById("drawerBackdrop");
|
|
||||||
const filterFTag = document.getElementById("pexpo-core-tag-toggle");
|
|
||||||
|
|
||||||
// Element for MultiSelect
|
|
||||||
const filterTagsSelect = document.getElementById("pexpo-core-tags");
|
|
||||||
|
|
||||||
const qInput = document.getElementById("q");
|
|
||||||
const masonry = document.getElementById("masonry");
|
|
||||||
const measure = document.getElementById("measure");
|
|
||||||
|
|
||||||
const count = document.getElementById("count");
|
|
||||||
const layoutMeta = document.getElementById("layoutMeta");
|
|
||||||
const sortSelect = document.getElementById("sortSelect");
|
|
||||||
|
|
||||||
// ---------- Mock Data Source ----------
|
|
||||||
const DATA_WORDS = [
|
|
||||||
"apple","river","mountain","cloud","stone","forest","breeze","candle","mirror","shadow",
|
|
||||||
"sunrise","sunset","ocean","island","valley","thunder","lightning","rain","snow","frost",
|
|
||||||
"ember","flame","smoke","ash","spark","comet","star","planet","orbit","galaxy",
|
|
||||||
"nebula","vacuum","gravity","rocket","satellite","signal","beacon","radar","sonar","echo",
|
|
||||||
"whisper","melody","rhythm","harmony","tempo","chord","lyric","verse","chorus","bridge",
|
|
||||||
"canvas","pigment","brush","palette","sketch","mural","statue","marble","bronze","copper",
|
|
||||||
"silver","golden","velvet","cotton","linen","silk","denim","leather","paper","ink",
|
|
||||||
"quill","notebook","journal","diary","letter","envelope","stamp","postcard","parcel","package",
|
|
||||||
"crate","barrel","bottle","jar","kettle","teapot","mug","cup","saucer","plate",
|
|
||||||
"bowl","spoon","fork","knife","napkin","table","chair","couch","pillow","blanket",
|
|
||||||
"curtain","window","door","hallway","kitchen","pantry","cellar","attic","ladder","hammer",
|
|
||||||
"nail","screw","wrench","pliers","drill","saw","chisel","ruler","compass","protractor",
|
|
||||||
"calculator","keyboard","mouse","screen","monitor","printer","scanner","speaker","microphone","camera",
|
|
||||||
"tripod","lens","shutter","focus","zoom","pixel","vector","shader","texture","model",
|
|
||||||
"render","frame","layer","filter","gradient","border","margin","padding","align","justify",
|
|
||||||
"center","left","right","top","bottom","header","footer","sidebar","menu","button",
|
|
||||||
"toggle","slider","checkbox","radio","select","option","input","output","submit","cancel",
|
|
||||||
"confirm","alert","notice","banner","badge","icon","symbol","logo","brand","slogan",
|
|
||||||
"motto","phrase","idiom","proverb","story","novel","poem","essay","article","report",
|
|
||||||
"summary","outline","draft","revision","edition","volume","chapter","page","paragraph","sentence",
|
|
||||||
"word","letterform","alphabet","grammar","syntax","semantics","context","nuance","tone","mood",
|
|
||||||
"theme","motif","plot","scene","actor","director","writer","editor","critic","reader",
|
|
||||||
"viewer","listener","audience","crowd","group","team","crew","squad","unit","league",
|
|
||||||
"match","game","round","score","point","level","stage","arena","field","court",
|
|
||||||
"track","trail","path","route","journey","voyage","trip","tour","adventure","quest",
|
|
||||||
"mission","challenge","victory","legend"
|
|
||||||
];
|
|
||||||
|
|
||||||
function makeResults(n, q = "") {
|
|
||||||
const out = [];
|
|
||||||
for (let i = 1; i <= n; i++) {
|
|
||||||
const score = Math.round(Math.random() * 100);
|
|
||||||
const extra = " ".repeat(Math.floor(Math.random() * 3)).replace(/ /g, "—");
|
|
||||||
|
|
||||||
let title = "";
|
|
||||||
if(q && Math.random() > 0.3) {
|
|
||||||
title = `${q} ${DATA_WORDS[Math.floor(Math.random() * DATA_WORDS.length)]}`;
|
|
||||||
} else {
|
|
||||||
title = Math.random() < 0.3
|
|
||||||
? `The ${DATA_WORDS[Math.floor(Math.random() * DATA_WORDS.length)]} of ${DATA_WORDS[Math.floor(Math.random() * DATA_WORDS.length)]}`
|
|
||||||
: `${DATA_WORDS[Math.floor(Math.random() * DATA_WORDS.length)]} ${DATA_WORDS[Math.floor(Math.random() * DATA_WORDS.length)]}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
out.push({
|
|
||||||
id: i,
|
|
||||||
title: title.charAt(0).toUpperCase() + title.slice(1),
|
|
||||||
url: "#",
|
|
||||||
tag: (() => {
|
|
||||||
const numberOfTags = Math.floor(Math.random() * 4) + 1;
|
|
||||||
return DATA_WORDS.slice().sort(() => 0.5 - Math.random()).slice(0, numberOfTags);
|
|
||||||
})(),
|
|
||||||
excerpt:
|
|
||||||
"Lorem ipsum dolor sit amet consectetur adipiscing elit. Consectetur adipiscing elit quisque faucibus ex sapien vitae." +
|
|
||||||
(score % 3 === 0 ? " Ex sapien vitae pellentesque sem placerat in id." : "") +
|
|
||||||
(extra ? "" : ""),
|
|
||||||
score,
|
|
||||||
image: `https://placehold.co/600x400?text=${encodeURIComponent(title)}`,
|
|
||||||
date: new Date(Date.now() - Math.random() * 1000 * 60 * 60 * 24 * 30).toISOString().slice(0, 10),
|
|
||||||
relevance: 0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- State ----------
|
|
||||||
let filters = {
|
|
||||||
q: "",
|
|
||||||
sort: "relevance",
|
|
||||||
tags: [], // Array of strings
|
|
||||||
force_tags: false, // AND vs OR logic
|
|
||||||
maxResults: 50
|
|
||||||
};
|
|
||||||
|
|
||||||
let activeSortKey = "relevance";
|
|
||||||
let results = [];
|
|
||||||
|
|
||||||
// ---------- Initialize MultiSelect Library ----------
|
|
||||||
// NOTE: This runs only if the library script is loaded
|
|
||||||
if (typeof MultiSelect !== 'undefined') {
|
|
||||||
|
|
||||||
// 1. Prepare Data for Lib ({value, text})
|
|
||||||
const multiSelectData = DATA_WORDS.sort().map(word => {
|
|
||||||
return {
|
|
||||||
value: word,
|
|
||||||
text: word.charAt(0).toUpperCase() + word.slice(1)
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// 2. Init
|
|
||||||
new MultiSelect(filterTagsSelect, {
|
|
||||||
placeholder: 'Címkék kiválasztása',
|
|
||||||
max: 20,
|
|
||||||
search: true,
|
|
||||||
selectAll: true,
|
|
||||||
onSelect: function(value, text, element) {
|
|
||||||
if (!filters.tags.includes(value)) {
|
|
||||||
filters.tags.push(value);
|
|
||||||
}
|
|
||||||
console.log('Updated filters.tags:', filters.tags);
|
|
||||||
},
|
|
||||||
onUnselect: function(value, text, element) {
|
|
||||||
filters.tags = filters.tags.filter(tag => tag !== value);
|
|
||||||
console.log('Updated filters.tags:', filters.tags);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.warn("MultiSelect library not found. Filters will not work without it.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- Sort Definitions ----------
|
|
||||||
const SORTS = {
|
|
||||||
relevance: { label: "Relevance", compare: (a, b) => (b.relevance - a.relevance) || (b.score - a.score) },
|
|
||||||
score_desc: { label: "Score (high → low)", compare: (a, b) => (b.score - a.score) },
|
|
||||||
date_desc: { label: "Date (new → old)", compare: (a, b) => new Date(b.date) - new Date(a.date) },
|
|
||||||
title_asc: { label: "Title (A → Z)", compare: (a, b) => (a.title || "").localeCompare(b.title || "") }
|
|
||||||
};
|
|
||||||
|
|
||||||
// ---------- Helpers ----------
|
|
||||||
function escapeHtml(str) {
|
|
||||||
return String(str).replace(/[&<>"']/g, s => ({
|
|
||||||
"&": "&", "<": "<", ">": ">", '"': """, "'": "'"
|
|
||||||
}[s]));
|
|
||||||
}
|
|
||||||
|
|
||||||
function cardEl(r) {
|
|
||||||
const div = document.createElement("div");
|
|
||||||
div.className = "pexpo-core-card";
|
|
||||||
div.innerHTML = `
|
|
||||||
<div class="pexpo-core-imageWrap">
|
|
||||||
<img src="${escapeHtml(r.image || '')}" alt="${escapeHtml(r.title)}" style="width:100%; border-radius:10px; object-fit:cover;" />
|
|
||||||
</div>
|
|
||||||
<div class="pexpo-core-cardTop">
|
|
||||||
<a href="${escapeHtml(r.url)}" class="pexpo-core-title">${escapeHtml(r.title)}</a>
|
|
||||||
</div>
|
|
||||||
<div class="pexpo-core-desc">${escapeHtml(r.excerpt)}</div>
|
|
||||||
<div class="pexpo-core-foot">
|
|
||||||
<div class="pexpo-core-tags">
|
|
||||||
${Array.isArray(r.tag) ? r.tag.map(element => `<span class="pexpo-core-tag">${escapeHtml(element)}</span>`).join('') : ''}
|
|
||||||
</div>
|
|
||||||
<div>${escapeHtml(r.date)}</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
return div;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- Logic: Data Fetch & Relevance ----------
|
|
||||||
function computeRelevance(r, q) {
|
|
||||||
const query = (q || "").trim().toLowerCase();
|
|
||||||
if (!query) return r.score;
|
|
||||||
|
|
||||||
const terms = query.split(/\s+/).filter(Boolean);
|
|
||||||
if (!terms.length) return r.score;
|
|
||||||
|
|
||||||
const title = (r.title || "").toLowerCase();
|
|
||||||
const hay = `${r.title} ${r.excerpt} ${r.tag.join(' ')}`.toLowerCase();
|
|
||||||
|
|
||||||
let hits = 0;
|
|
||||||
let titleHits = 0;
|
|
||||||
for (const t of terms) {
|
|
||||||
if (hay.includes(t)) hits++;
|
|
||||||
if (title.includes(t)) titleHits++;
|
|
||||||
}
|
|
||||||
return (hits * 30) + (titleHits * 25) + (r.score * 0.35);
|
|
||||||
}
|
|
||||||
|
|
||||||
function recomputeRelevance(q) {
|
|
||||||
for (const r of results) r.relevance = computeRelevance(r, q);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchData(query = "") {
|
|
||||||
masonry.style.opacity = "0.5";
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 200));
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 1. Generate Raw Data
|
|
||||||
const count = Number(filters.maxResults) || 50;
|
|
||||||
let generated = makeResults(Math.min(count, 100), query);
|
|
||||||
|
|
||||||
// 2. Apply Filters (Tags)
|
|
||||||
if (filters.tags && filters.tags.length > 0) {
|
|
||||||
generated = generated.filter(item => {
|
|
||||||
// Does the item have at least one of the selected tags?
|
|
||||||
return item.tag.some(t => filters.tags.includes(t));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
results = generated;
|
|
||||||
|
|
||||||
// 3. Compute relevance
|
|
||||||
recomputeRelevance(query);
|
|
||||||
|
|
||||||
// 4. Trigger Layout
|
|
||||||
requestLayout();
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Mock generation failed:", error);
|
|
||||||
masonry.innerHTML = `<div style="padding:20px; color:red;">Hiba történt a keresés során.</div>`;
|
|
||||||
} finally {
|
|
||||||
masonry.style.opacity = "1";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- Layout & Masonry Logic ----------
|
|
||||||
const minCard = () => Number(getComputedStyle(document.documentElement).getPropertyValue("--cardMin")) || 240;
|
|
||||||
const gap = () => Number(getComputedStyle(document.documentElement).getPropertyValue("--gap")) || 12;
|
|
||||||
|
|
||||||
let layoutQueued = false;
|
|
||||||
function requestLayout() {
|
|
||||||
if (layoutQueued) return;
|
|
||||||
layoutQueued = true;
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
layoutQueued = false;
|
|
||||||
applyMasonry();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getColumnCount() {
|
|
||||||
const w = masonry.clientWidth || masonry.getBoundingClientRect().width || 1;
|
|
||||||
const mc = minCard();
|
|
||||||
const g = gap();
|
|
||||||
return Math.max(1, Math.floor((w + g) / (mc + g)));
|
|
||||||
}
|
|
||||||
|
|
||||||
function measureCardHeights(cols, list) {
|
|
||||||
const w = masonry.clientWidth || 1;
|
|
||||||
const g = gap();
|
|
||||||
const colW = Math.floor((w - (cols - 1) * g) / cols);
|
|
||||||
measure.style.width = colW + "px";
|
|
||||||
measure.innerHTML = "";
|
|
||||||
|
|
||||||
const measured = list.map((r, idx) => {
|
|
||||||
const el = cardEl(r);
|
|
||||||
measure.appendChild(el);
|
|
||||||
const h = el.offsetHeight;
|
|
||||||
measure.removeChild(el);
|
|
||||||
return { r, idx, h };
|
|
||||||
});
|
|
||||||
|
|
||||||
return { measured, colW };
|
|
||||||
}
|
|
||||||
|
|
||||||
function packRankAware(measured, cols, K = 6) {
|
|
||||||
const colHeights = new Array(cols).fill(0);
|
|
||||||
const placements = [];
|
|
||||||
const queue = measured.slice();
|
|
||||||
|
|
||||||
while (queue.length) {
|
|
||||||
let bestCol = 0;
|
|
||||||
for (let c = 1; c < cols; c++) {
|
|
||||||
if (colHeights[c] < colHeights[bestCol]) bestCol = c;
|
|
||||||
}
|
|
||||||
const lookN = Math.min(K, queue.length);
|
|
||||||
let pick = 0;
|
|
||||||
for (let i = 1; i < lookN; i++) {
|
|
||||||
if (queue[i].h > queue[pick].h) pick = i;
|
|
||||||
}
|
|
||||||
const picked = queue.splice(pick, 1)[0];
|
|
||||||
placements.push({ item: picked, col: bestCol });
|
|
||||||
colHeights[bestCol] += picked.h + gap();
|
|
||||||
}
|
|
||||||
return placements;
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyMasonry() {
|
|
||||||
const n = results.length || 0;
|
|
||||||
count.textContent = n;
|
|
||||||
masonry.innerHTML = "";
|
|
||||||
|
|
||||||
if (n === 0) {
|
|
||||||
masonry.innerHTML = `<div style="padding:20px; color:#666;">Nincs a szűrőnek megfelelő találat.</div>`;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const cols = getColumnCount();
|
|
||||||
const colEls = [];
|
|
||||||
for (let c = 0; c < cols; c++) {
|
|
||||||
const col = document.createElement("div");
|
|
||||||
col.className = "pexpo-core-mCol";
|
|
||||||
masonry.appendChild(col);
|
|
||||||
colEls.push(col);
|
|
||||||
}
|
|
||||||
|
|
||||||
const sorter = SORTS[activeSortKey] || SORTS.relevance;
|
|
||||||
const sorted = results.slice().sort(sorter.compare);
|
|
||||||
const { measured } = measureCardHeights(cols, sorted);
|
|
||||||
const placements = packRankAware(measured, cols, 6);
|
|
||||||
|
|
||||||
for (const p of placements) {
|
|
||||||
colEls[p.col].appendChild(cardEl(p.item.r));
|
|
||||||
}
|
|
||||||
|
|
||||||
layoutMeta.textContent = `${cols} cols • ${SORTS[activeSortKey]?.label || "Relevance"}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- UI Events ----------
|
|
||||||
|
|
||||||
// Sort Dropdown
|
|
||||||
if (sortSelect) {
|
|
||||||
sortSelect.innerHTML = Object.entries(SORTS)
|
|
||||||
.map(([k, def]) => `<option value="${escapeHtml(k)}">${escapeHtml(def.label)}</option>`)
|
|
||||||
.join("");
|
|
||||||
sortSelect.value = activeSortKey;
|
|
||||||
sortSelect.addEventListener("change", () => {
|
|
||||||
activeSortKey = sortSelect.value;
|
|
||||||
filters.sort = activeSortKey;
|
|
||||||
requestLayout();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search
|
|
||||||
qInput.addEventListener("keyup", (e) => { // Changed to keyup for live feeling, or keep Enter
|
|
||||||
if (e.key === "Enter") {
|
|
||||||
filters.q = qInput.value.trim();
|
|
||||||
fetchData(filters.q);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Tag Toggle
|
|
||||||
filterFTag.addEventListener("change", () => {
|
|
||||||
filters.force_tags = filterFTag.checked;
|
|
||||||
console.log("Force tags:", filters.force_tags);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Filter Drawer Logic
|
|
||||||
function syncTopbarHeight() {
|
|
||||||
const h = topbar.offsetHeight;
|
|
||||||
document.documentElement.style.setProperty("--topbarH", h + "px");
|
|
||||||
}
|
|
||||||
|
|
||||||
function setOpen(open) {
|
|
||||||
filterWrap.classList.toggle("pexpo-core-open", open);
|
|
||||||
filterBtn.setAttribute("aria-expanded", String(open));
|
|
||||||
filterDrawer.classList.toggle("pexpo-core-open", open);
|
|
||||||
filterDrawer.setAttribute("aria-hidden", String(!open));
|
|
||||||
drawerBackdrop.classList.toggle("pexpo-core-show", open);
|
|
||||||
shell.classList.toggle("pexpo-core-drawerOpen", open);
|
|
||||||
syncTopbarHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
filterBtn.addEventListener("click", () => setOpen(!filterDrawer.classList.contains("pexpo-core-open")));
|
|
||||||
drawerBackdrop.addEventListener("click", () => setOpen(false));
|
|
||||||
document.addEventListener("keydown", (e) => {
|
|
||||||
if (e.key === "Escape" && filterDrawer.classList.contains("pexpo-core-open")) setOpen(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Resize Observer
|
|
||||||
const ro = new ResizeObserver(() => {
|
|
||||||
syncTopbarHeight();
|
|
||||||
requestLayout();
|
|
||||||
});
|
|
||||||
ro.observe(shell);
|
|
||||||
ro.observe(masonry);
|
|
||||||
|
|
||||||
// Initial Load
|
|
||||||
syncTopbarHeight();
|
|
||||||
fetchData("");
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<script src="js/multiselect.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Reference in New Issue
Block a user