PageSourceSearch

https://www.groupcal.app/wp-content/themes/24me/modules/theme/assets/js/features-menu.js?ver=1789693063

js groupcal.app collected 2026-09-24 08:55:00 UTC 10,881 bytes, 183 lines download raw bytes

1jQuery(function($){
2  // =================================================================
3  // 1. DATA STRUCTURE
4  // =================================================================
5  const categories = {
6    sharing: {
7      pageSlug: 'features-seamless-sharing-collaboration',
8      items: [
9        { title: "Create Unlimited Shared Calendars", id: "shared-calendars", description: "Set up distinct, shared schedules for every group, team and community", icon: headerMenuData.image_path + "create-unlimited_shared_calendars_menu.jpg" },
10        { title: "Instant Calendar Sharing", id: "instant-calendar", description: "Invite new members with a simple link or phone number.", icon: headerMenuData.image_path + "instant_calendar_sharing_menu.jpg" },
11        { title: "One-Click Member Join", id: "one-click-member", description: "Give members seamless and immediate access to your calendar.", icon: headerMenuData.image_path + "one_click_join_menu.jpg" },
12        { title: "Share Personal Calendars", id: "share_personal_calendars", description: "Share your existing Google, Outlook, and iCloud calendar accounts", icon: headerMenuData.image_path + "integrate_personal_calendars_menu.jpg" },
13        { title: "Real-Time Notifications", id: "real-time-notifications", description: "Automated notifications & reminders to your group and audience", icon: headerMenuData.image_path + "notify_menu.jpg" },
14        { title: "Chat-Like Calendar Updates", id: "chat-like-updates", description: "An intuitive way to see recent calendar changes easily", icon: headerMenuData.image_path + "chat_menu.jpg" },
15        { title: "Member Colors & Photos", id: "member-colors", description: "Visually organize members and clarify who owns which calendar event", icon: headerMenuData.image_path + "colors_photo_menu.jpg" },
16        { title: "Event Ownership", id: "event-ownership", description: "Clearly define responsibility and accountability for specific events", icon: headerMenuData.image_path + "event_ownership_menu.jpg" }      
17      ]
18    },
19    calendar: {
20      pageSlug: 'features-centralized-calendar-management',
21      items: [
22        { title: "Manage Multiple Calendars", id: "centralized-calendar-management", description: "Effortlessly oversee all your distinct shared schedules in one place", icon: headerMenuData.image_path + "manage_shared_calendars_menu.jpg" },
23        { title: "Customize Each Calendars", id: "customize_each_calendars", description: "Set unique visuals and default settings for every shared calendar", icon: headerMenuData.image_path + "customize_menu.jpg" },
24        { title: "Unified Calendar View", id: "unified_calendar_view", description: "See all your personal and shared calendars on a unified calendar view", icon: headerMenuData.image_path + "unified_calendar_view_menu.jpg" },
25        { title: "Sync Events Across Calendars", id: "sync_events_across_calendars", description: "Sync events across multiple selected calendars with master schedules", icon: headerMenuData.image_path + "sync_across_calendars_menu.jpg" },
26        { title: "Integrate Personal Calendars", id: "integrate_personal_calendars", description: "Connect your existing Google, Outlook, and iCloud calendar accounts", icon: headerMenuData.image_path + "integrate_personal_calendars_menu.jpg" },
27        { title: "Manage From Any Device", id: "manage_from_any_device", description: "Full calendar management capabilities from your computer or mobile phone", icon: headerMenuData.image_path + "access_anywhere_2_menu.jpg" },
28      ]
29    },
30    permissions: {
31      pageSlug: 'powerful-permissions-control',
32      items: [
33        { title: "Calendar Members Roles", id: "calendar-members-roles", description: "Owner, Admin, or Member Roles to Control Access", icon: headerMenuData.image_path + "calendar_members_roles_menu.jpg" },
34        { title: "Control Event Editing", id: "control-event-editing", description: "Determine precisely who has permission to add or modify events", icon: headerMenuData.image_path + "control-edit_access_menu.jpg" },
35        { title: "Edit Own Events Only", id: "edit_own_events_only", description: "Protect individual member events from being changed by others", icon: headerMenuData.image_path + "edit_own_events_menu.jpg" },
36        { title: "Control Member Adding", id: "control-member-adding", description: "Manage whether members can invite and add others to calendars", icon: headerMenuData.image_path + "control_member_adding_menu.jpg" },
37        { title: "Control Calendar Branding", id: "control-calendar-branding", description: "Manage who can change the calendar's name, photo, and color", icon: headerMenuData.image_path + "control_calendar_branding_menu.jpg" },
38        { title: "Set Event Detail Visibility", id: "set-event-detail-visibility", description: "Control who can view full, detailed information for each event", icon: headerMenuData.image_path + "control_event_visibility_menu.jpg" },
39        { title: "Assign Event Ownership", id: "assign-event-ownership", description: "Assign responsibility and ownership for calendar events", icon: headerMenuData.image_path + "assign_event_ownership_menu.jpg" },
40      ]
41    },
42    brand: {
43      pageSlug: 'features-brand-publish-embed',
44      items:[
45        { title: "Public Calendar Channels", id: "public-calendar-channels", description: "Publish a Searchable Calendar to Engage with an Unlimited Audience", icon: headerMenuData.image_path + "calendar_channels_menu.jpg" },
46        { title: "Brand Your Calendar", id: "brand-your-calendar", description: "Customize your public calendar with a unique photo, color, and description", icon: headerMenuData.image_path + "brand_
46your_calendar_menu.jpg" },
47        { title: "Visual Card Layout", id: "visual-card-layout", description: "Transform your website’s schedule into a visual event feed", icon: headerMenuData.image_path + "visual_card_layout_menu.jpg" },
48        { title: "Embed On Your Website", id: "embed-on-your-website", description: "Seamlessly integrate your live calendar directly onto your website", icon: headerMenuData.image_path + "embed_calendar_on_websites_menu.jpg" },
49        { title: "Calendar Verification Badge", id: "calendar-verification-badge", description: "Establish trust and authenticity with an official verification badge", icon: headerMenuData.image_path + "calendar_verification_menu.jpg" }
50      ]
51    }
52  };
53
54  // =================================================================
55  // 2. DOM ELEMENTS AND STATE
56  // =================================================================
57  var $featureList = $('#featureList');
58  var $pageLinks = $('.page-link');
59  var $popup = $('.navigation-popup');
60  var $featuresMenuItem = $('.features-menu-item');
61  var $resourcesMenuItem = $('.resources-parent'); // --- NEW --- A selector for the resources menu parent
62  var $useCaseMenuItem = $('.use-case-menu-parent'); // --- NEW --- A selector for the use case menu parent
63  var activeCategory = $pageLinks.filter('.active').data('category') || 'sharing';
64
65  // =================================================================
66  // 3. CORE FUNCTIONS
67  // =================================================================
68  function updateFeatures(category) {
69    $featureList.css('opacity', 0);
70    setTimeout(function(){
71      $featureList.empty();
72      
73      const categoryData = categories[category];
74      if (!categoryData) return; // Safety check
75
76      const featureCategoryPage = categoryData.pageSlug;
77
78      $.each(categoryData.items, function(i, feature){
79        var $subLink = $('<a>', {
80          class: 'sub-link',
81          href: siteBaseUrl + '/' + featureCategoryPage + '#' + feature.id,
82          html: `
83            <img class="img-2" src="${feature.icon}" />
84            <div class="text">
85              <div class="individuals">${feature.title}</div>
86              <p class="p">${feature.description}</p>
87            </div>
88          `
89        });
90        $subLink.on('click', function(){
91          $popup.hide();
92          $featuresMenuItem.removeClass('active');
93        });
94        $featureList.append($subLink);
95      });
96      requestAnimationFrame(function(){
97        $featureList.css('opacity', 1);
98      });
99    }, 150);
100  }
101
102  function selectCategory(category) {
103    if (category === activeCategory) {
104      return; // Do nothing if hovering over the already active category
105    }
106    activeCategory = category;
107    $pageLinks.removeClass('active');
108    $pageLinks.filter('[data-category="' + category + '"]').addClass('active');
109    updateFeatures(category);
110  }
111
112  // =================================================================
113  // 4. EVENT HANDLERS
114  // =================================================================
115
116  // Main Menu Open/Close on "Features" click
117  $featuresMenuItem.on('click', function (e) {
118    e.preventDefault();
119    e.stopPropagation();
120
121    // --- NEW --- Close the resources menu before opening this one
122    $resourcesMenuItem.find('.sub-menu').removeClass('show');
123    $resourcesMenuItem.removeClass('active');
124
125    $useCaseMenuItem.find('.sub-menu').removeClass('show');
126    $useCaseMenuItem.removeClass('active');
127
128    $popup.toggle();
129    $featuresMenuItem.toggleClass('active');
130  });
131
132  // --- NEW --- When clicking the Resources menu, close the Features menu
133  $resourcesMenuItem.on('click', function(e) {
134      // We don't stop propagation here, we let the theme's JS do its thing.
135      // We just make sure the other menu is closed.
136      $popup.hide();
137      $featuresMenuItem.removeClass('active');
138  });
139
140  $useCaseMenuItem.on('click', function(e) {
141      // We don't stop propagation here, we let the theme's JS do its thing.
142      // We just make sure the other menu is closed.
143      $popup.hide();
144      $featuresMenuItem.removeClass('active');
145  });
146
147  // Prevent closing the popup when clicking inside it
148  $popup.on('click', function(e){
149    e.stopPropagation();
150  });
151
152  // Switch category content on hover
153  $pageLinks.on('mouseenter', function(){
154    var cat = $(this).data('category');
155    selectCategory(cat);
156  });
157
158  // Hide menu on outside click
159  $(document).on('click', function(e){
160    if ($popup.is(':visible')) {
161      if (!$(e.target).closest('.navigation-popup, .features-menu-item').length) {
162        $popup.hide();
163        $featuresMenuItem.removeClass('active');
164      }
165    }
166  });
167
168  // Hide menu on ESC key press
169  $(document).on('keydown', function(e){
170    if(e.key === "Escape"){
171      $popup.hide();
172      $featuresMenuItem.removeClass('active');
173    }
174  });
175
176  // =================================================================
177  // 5. INITIALIZATION
178  // =================================================================
179  $pageLinks.removeClass('active');
180  $pageLinks.filter('[data-category="' + activeCategory + '"]').addClass('active');
181  updateFeatures(activeCategory);
182
183});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.