Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: load and format lend menu data #314

Open
wants to merge 14 commits into
base: www-header
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions @kiva/kv-components/utils/arrayUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Groups an array of objects by a specified key.
* @param {Array} array - The array of objects to be grouped.
* @param {string} groupByKey - The key based on which the grouping should be done.
* @returns {Object} - An object where keys are unique values of the specified key,
* and values are arrays of objects that share the same key value.
*/

const groupBy = (array, groupByKey) => {
return array.reduce((groups, currentItem) => {
const keyValue = currentItem[groupByKey];
if (!groups[keyValue]) {
// eslint-disable-next-line no-param-reassign
groups[keyValue] = [];
}
groups[keyValue].push(currentItem);
return groups;
}, {});
};

/**
* Returns a comparator function for sorting an array of objects by a specified key.
* @param {string} key - The key based on which the sorting should be done.
* @returns {Function} - A comparator function that can be used with the Array.sort() method.
*/
const sortBy = (key) => {
// eslint-disable-next-line no-nested-ternary
return (a, b) => ((a[key] > b[key]) ? 1 : ((b[key] > a[key]) ? -1 : 0));
};

export { groupBy, sortBy };
23 changes: 23 additions & 0 deletions @kiva/kv-components/utils/comparators.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,26 @@ export function startsWith(query, key) {
return bi === 0 ? 1 : abc()(as, bs);
};
}

/**
* Returns a comparison function to be used by Array.prototype.sort(). The comparison function will
* sort elements to match their relative position in the given list.
*
* const list = ['a', 'b', 'c', 'd'];
* const arrayToSort = ['d', 'a'];
* arrayToSort.sort(indexIn(list)); // will return ['a','d']
*
* @param {array} list
* @param {string} [key] - compare property 'key' of elements rather than the elements themselves
* @returns {function}
*/
export function indexIn(list, key) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding this!

if (!Array.isArray(list)) {
throw new TypeError('list must be an array');
}
return (a, b) => {
const as = key ? a[key] : a;
const bs = key ? b[key] : b;
return list.indexOf(as) < list.indexOf(bs) ? -1 : 1;
};
}
11 changes: 2 additions & 9 deletions @kiva/kv-components/utils/siteSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useEventListener } from './event';
import markMatches from './markMatches';
import { hasExcludedQueryParams } from './loanSearch/queryParamUtils';
import SearchEngine from './searchEngine';
import { groupBy } from './arrayUtils';

// instances
const instances = {};
Expand Down Expand Up @@ -37,15 +38,7 @@ function makeInstance() {

const suggestionSections = computed(() => {
// Group the results by their group name
const resultGroups = rawSuggestions.value.reduce((groups, result) => {
const { group } = result;
if (!groups[group]) {
// eslint-disable-next-line no-param-reassign
groups[group] = [];
}
groups[group].push(result);
return groups;
}, {});
const resultGroups = groupBy(rawSuggestions.value, 'group');

// From the groups, build the sections of suggestions to display
return Object.keys(resultGroups)
Expand Down
47 changes: 41 additions & 6 deletions @kiva/kv-components/vue/KvWwwHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
</transition>
<!-- logo -->
<a
v-kv-track-event="['TopNav', 'click-Logo']"
href="/"
class="
tw-px-1 tw-py-2
Expand Down Expand Up @@ -82,7 +83,7 @@
v-show="menuOpen || searchOpen"
class="
tw-absolute tw-z-modal
tw-top-7.5 tw-inset-x-0 tw-bottom-0
tw-top-7.5 tw-inset-x-0
tw-bg-eco-green-4
tw-bg-opacity-[50%]
"
Expand All @@ -96,8 +97,14 @@
<div class="header-margins tw-px-2.5">
<component
:is="menuComponent"
ref="menuComponentInstance"
:logged-in="loggedIn"
:login-url="loginUrl"
:user-id="userId"
:balance="balance"
:is-borrower="isBorrower"
:is-trustee="isTrustee"
@load-lend-menu-data="emitLendMenuEvent"
/>
</div>
</div>
Expand All @@ -108,14 +115,13 @@

<script>
import {
ref,
ref, shallowRef,
} from 'vue-demi';
import {
ecoForestTheme,
} from '@kiva/kv-tokens/configs/kivaColors.cjs';
import KvHeaderLinkBar from './KvWwwHeader/KvHeaderLinkBar.vue';
import KvHeaderLogo from './KvWwwHeader/KvHeaderLogo.vue';
import KvHeaderMobileMenu from './KvWwwHeader/KvHeaderMobileMenu.vue';
import KvHeaderSearchBar from './KvWwwHeader/KvHeaderSearchBar.vue';
import KvThemeProvider from './KvThemeProvider.vue';
import KvHeaderSearchSuggestions from './KvWwwHeader/KvHeaderSearchSuggestions.vue';
Expand All @@ -124,7 +130,6 @@ export default {
components: {
KvHeaderLinkBar,
KvHeaderLogo,
KvHeaderMobileMenu,
KvHeaderSearchBar,
KvThemeProvider,
KvHeaderSearchSuggestions,
Expand All @@ -142,14 +147,31 @@ export default {
type: String,
default: '/ui-login',
},
balance: {
type: Number,
default: 0,
},
isBorrower: {
type: Boolean,
default: false,
},
isTrustee: {
type: Boolean,
default: false,
},
},
setup() {
emits: [
'load-lend-menu-data',
],
setup(props, { emit }) {
const linksVisible = ref(true);
const searchBar = ref(null);
const searchOpen = ref(false);
const activeHeaderItem = ref(null);
const menuOpen = ref(false);
const menuComponent = ref(null);
const menuComponent = shallowRef(null);
const menuComponentInstance = ref(null);
const userId = ref(props.userId);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

userId should be declared as a prop, and then it will be available in the template and won't need to be declared here.


let menuCloseTimeout;

Expand Down Expand Up @@ -196,12 +218,23 @@ export default {
searchBar.value?.getSuggestions(apollo);
};

const loadMenuData = (apollo) => {
menuComponentInstance.value?.onLoad(apollo);
};

// This event will be used as a signal to call loadMenuData
const emitLendMenuEvent = () => {
emit('load-lend-menu-data');
};

return {
ecoForestTheme,
userId,

afterLinksNotVisible,
afterSearchClosed,
afterSearchOpen,
emitLendMenuEvent,

linksVisible,
searchOpen,
Expand All @@ -211,10 +244,12 @@ export default {
openSearch,
closeSearch,
getSuggestions,
loadMenuData,

activeHeaderItem,
searchBar,
menuComponent,
menuComponentInstance,
};
},
};
Expand Down
16 changes: 12 additions & 4 deletions @kiva/kv-components/vue/KvWwwHeader/KvHeaderLinkBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<!-- lend -->
<a
ref="lendButton"
v-kv-track-event="['TopNav', 'click-Lend']"
href="/lend-by-category"
class="
tw-px-1.5 tw-py-1 tw-mx-1
Expand Down Expand Up @@ -88,6 +89,7 @@
<a
v-if="basketCount > 0"
ref="basketLink"
v-kv-track-event="['TopNav', 'click-Basket']"
href="/basket"
class="header-link tw-relative"
:class="{'tw-text-tertiary': !!openMenuItem}"
Expand All @@ -100,6 +102,7 @@
<!-- search icon -->
<button
ref="searchButton"
v-kv-track-event="['TopNav', 'click-Search-toggle']"
class="header-link"
:class="{
'tw-text-tertiary': !!openMenuItem
Expand All @@ -112,6 +115,7 @@
<a
v-if="!loggedIn"
ref="signInLink"
v-kv-track-event="['TopNav', 'click-Sign-in']"
:href="loginUrl"
class="header-link tw-hidden lg:tw-block"
:class="{'tw-text-tertiary': !!openMenuItem}"
Expand All @@ -121,6 +125,9 @@
<!-- 3-bar menu (sm) -->
<button
ref="menuButton"
v-kv-track-event="openMenuItem === KvHeaderMobileMenu
? ['TopNav', 'click-Hamburger-menu']
: null"
class="header-link tw-inline-flex lg:tw-hidden"
:class="{
'tw-text-tertiary': openMenuItem && openMenuItem !== KvHeaderMobileMenu
Expand All @@ -135,6 +142,7 @@

<script>
import {
defineAsyncComponent,
ref,
} from 'vue-demi';
import { mdiAccountCircle, mdiMenu } from '@mdi/js';
Expand All @@ -143,9 +151,9 @@ import KvIconChevron from '../KvIconChevron.vue';
import KvIconSearch from '../KvIconSearch.vue';
import KvMaterialIcon from '../KvMaterialIcon.vue';

const KvHeaderMobileMenu = () => import('./KvHeaderMobileMenu.vue');
const KvHeaderMyKivaMenu = () => import('./KvHeaderMyKivaMenu.vue');
const KvLendMenu = () => import('./LendMenu/KvLendMenu.vue');
const KvHeaderMobileMenu = defineAsyncComponent(() => import('./KvHeaderMobileMenu.vue'));
const KvHeaderMyKivaMenu = defineAsyncComponent(() => import('./KvHeaderMyKivaMenu.vue'));
const KvLendMenu = defineAsyncComponent(() => import('./LendMenu/KvLendMenu.vue'));

export default {
components: {
Expand All @@ -164,7 +172,7 @@ export default {
default: 0,
},
openMenuItem: {
type: [Element, Function],
type: [Object, Function],
default: null,
},
loginUrl: {
Expand Down
5 changes: 5 additions & 0 deletions @kiva/kv-components/vue/KvWwwHeader/KvHeaderMobileMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,32 @@
<nav class="tw--mt-0.5 tw-pb-0.5 tw-flex tw-flex-col tw-items-end lg:tw-hidden tw-font-medium">
<kv-header-menu-link
v-if="!loggedIn"
v-kv-track-event="['TopNav', 'click-menu-Sign-in']"
:href="loginUrl"
>
Sign in
</kv-header-menu-link>
<kv-header-menu-link
v-kv-track-event="['TopNav', 'click-menu-Support-kiva']"
href="/donate/supportus"
>
Support Kiva
</kv-header-menu-link>
<kv-header-menu-link
v-if="!loggedIn"
v-kv-track-event="['TopNav', 'click-menu-Borrow']"
href="/borrow"
>
Borrow
</kv-header-menu-link>
<kv-header-menu-link
v-kv-track-event="['TopNav', 'click-menu-About-us']"
href="/about"
>
About us
</kv-header-menu-link>
<kv-header-menu-link
v-kv-track-event="['TopNav', 'click-menu-Partner-with-us']"
href="/about/partner-with-us"
>
Partner with us
Expand Down
28 changes: 27 additions & 1 deletion @kiva/kv-components/vue/KvWwwHeader/KvHeaderMyKivaMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
>
<span>Portfolio</span>
<span class="tw-text-secondary">|</span>
<span class="tw-text-eco-green-3">{{ balance }}</span>
<span class="tw-text-eco-green-3">{{ numeral(balance).format('$0') }}</span>
</kv-header-menu-link>
<kv-header-menu-link
href="/teams/my-teams"
Expand All @@ -23,6 +23,18 @@
>
Settings
</kv-header-menu-link>
<kv-header-menu-link
v-if="isBorrower"
href="/my/borrower"
>
Borrower Dashboard
</kv-header-menu-link>
<kv-header-menu-link
v-if="isTrustee"
href="/my/trustee"
>
Trustee Dashboard
</kv-header-menu-link>
<kv-header-menu-link
href="/ui-logout"
>
Expand All @@ -32,6 +44,7 @@
</template>

<script>
import numeral from 'numeral';
import KvHeaderMenuLink from './KvHeaderMenuLink.vue';

export default {
Expand All @@ -43,6 +56,19 @@ export default {
type: Number,
default: 0,
},
isBorrower: {
type: Boolean,
default: false,
},
isTrustee: {
type: Boolean,
default: false,
},
},
setup() {
return {
numeral,
};
},
};
</script>
1 change: 1 addition & 0 deletions @kiva/kv-components/vue/KvWwwHeader/KvHeaderSearchBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
</div>
<!-- cancel search -->
<button
v-kv-track-event="['TopNav', 'click-cancel-search']"
class="tw-px-2.5 tw-transition-opacity"
:class="{
'tw-opacity-full tw-duration-300': searchExitVisible,
Expand Down
Loading
Loading