harambee starlets

Odemba names final Harambee Starlets squad for WAFCON as four players miss out

Odemba names final Harambee Starlets squad for WAFCON as four players miss out

Listen to article

4 min listen
Audio reading is not supported on this browser.


Ready

Thanks for listening. Continue with a related story, or tap the speaker icon on the next page to listen.


Related story

Cheche backs Junior Starlets to rout South Africa and book FIFA U17 World Cup spot

Erick Kariuki

 · 

1 day ago


Read next


Opens a fresh page.

The final squad will be led by experienced goalkeeper Annedy Kundu alongside Lilian Awuor and Vivian Shiyonzo, while the defensive department comprises Leah Andiema, Elizabeth Ochaka, Ruth Ingosi, Vivian Nasaka, Enez Mango, Euphrasier Shilwatso, Norah Ann and Mary Nthambi.

Harambee Starlets head coach Beldine Odemba has named her final 25-player squad for the 2026 Women’s Africa Cup of Nations (WAFCON), trimming four players from the provisional squad as Kenya intensifies preparations for its return to the continental tournament after a decade-long absence.
Odemba’s final selection retains the core of the squad that secured qualification for the tournament, while goalkeeper Lilian Adhiambo, defender Elizabeth Muteshi and forwards Elizabeth Mideva, Catherine Khaemba and Tumaini Waliaula are the players who miss out on the travelling party to Morocco.
The final squad will be led by experienced goalkeeper Annedy Kundu alongside Lilian Awuor and Vivian Shiyonzo, while the defensive department comprises Leah Andiema, Elizabeth Ochaka, Ruth Ingosi, Vivian Nasaka, Enez Mango, Euphrasier Shilwatso, Norah Ann and Mary Nthambi.
In midfield, captain Mwanalima Adam will be joined by Martha Amunyolete, Tereza Engesha, Fasila Adhiambo, Lorna Nyarinda, Mercy Airo, Airin Madalina and Shaline Nambengele, forming the engine room that Odemba will rely on throughout the competition.
The attacking unit features Shirleen Opisa, Eglay Mukhwana, Marion Serenge, Violet Nanjala and Valerie Nekesa, with the technical bench banking on the quintet to provide the goals as Kenya faces some of the continent’s strongest sides.
The omission of Lilian Adhiambo leaves Odemba with three goalkeepers in line with CAF tournament regulations, while Elizabeth Muteshi narrowly misses out in defence. In the attack, Elizabeth Mideva, Catherine Khaemba and Tumaini Waliaula have also been left out following the conclusion of the team’s final assessment in camp.
Kenya will head to Morocco seeking to make an impact in only their second appearance at the Women’s Africa Cup of Nations and their first since making their tournament debut in 2016.
The Harambee Starlets have been drawn in Group A alongside hosts Morocco, Senegal and Algeria. They begin their campaign against Morocco on July 26 at the Moulay El Hassan Stadium in Rabat before facing Senegal on July 30 and Algeria on August 3.
With the final squad now confirmed, Odemba’s focus shifts to fine-tuning the team ahead of a challenging group-stage campaign as the Starlets look to announce their return to Africa’s biggest women’s football tournament with a strong showing.
Final Harambee Starlets squad
Goalkeepers: Annedy Kundu, Lilian Awuor, Vivian Shiyonzo.
Defenders: Leah Andiema, Elizabeth Ochaka, Ruth Ingosi, Vivian Nasaka, Enez Mango, Euphrasier Shilwatso, Norah Ann, and Mary Nthambi.
Midfielders: Mwanalima Adam, Martha Amunyolete, Tereza Engesha, Fasila Adhiambo, Lorna Nyarinda, Mercy Airo, Airin Madalina, Shaline Nambengele.
Forwards: Shirleen Opisa, Eglay Mukhwana, Marion Serenge, Violet Nanjala, Valerie Nekesa.
Players omitted from the provisional squad: Lilian Adhiambo, Elizabeth Muteshi, Elizabeth Mideva, Catherine Khaemba and Tumaini Waliaula.

`;
}

return “;
}

function commentActionsMarkup(comment, canComment) {
const likeLabel = comment.liked_by_me ? ‘Liked’ : ‘Like’;
const likeCount = Number(comment.like_count || 0) > 0
? “
: ”;

const likeButton = canComment && comment.status === ‘approved’
? “
: “;

const replyButton = canComment && comment.status === ‘approved’
? “
: ”;

return `

`;
}

function commentMarkup(comment, canComment, isReply = false) {
const pendingBadge = comment.status && comment.status !== ‘approved’
? “
: ”;

const edited = comment.is_edited
? “
: ”;

const repliesHtml = Array.isArray(comment.replies) && comment.replies.length
? `

`
: “;

return `

`;
}

function replyFormMarkup(commentId) {
return `

`;
}

function setNotice(widget, message, type = ‘info’) {
const notice = widget.querySelector(‘[data-role=”notice”]’);
if (!notice) return;

if (!message) {
notice.hidden = true;
notice.textContent = ”;
notice.classList.remove(‘is-error’);
return;
}

notice.hidden = false;
notice.textContent = message;
notice.classList.toggle(‘is-error’, type === ‘error’);
}

function setCount(widget, total) {
const count = widget.querySelector(‘[data-role=”count”]’);
if (!count) return;

const num = Number(total || 0);
count.textContent = num === 1 ? ‘1 comment’ : `${num} comments`;
}

function openReplyBox(widget, commentId) {
widget.querySelectorAll(‘[data-role=”reply-box”]’).forEach(box => {
box.hidden = true;
box.innerHTML = ”;
});

const targetItem = widget.querySelector(`.ev-comments__item[data-comment-id=”${commentId}”]`);
if (!targetItem) return;

const replyBox = targetItem.querySelector(‘[data-role=”reply-box”]’);
if (!replyBox) return;

replyBox.hidden = false;
replyBox.innerHTML = replyFormMarkup(commentId);

const textarea = replyBox.querySelector(‘textarea’);
if (textarea) textarea.focus();
}

function closeReplyBox(container) {
if (!container) return;
container.hidden = true;
container.innerHTML = ”;
}

async function initCommentsWidget(widget) {
const state = {
articleId: Number(widget.dataset.articleId),
loadUrl: widget.dataset.loadUrl,
storeUrl: widget.dataset.storeUrl,
commentsBaseUrl: widget.dataset.commentsBaseUrl,
canComment: widget.dataset.canComment === ‘1’,
page: 1,
perPage: 10,
sort: ‘newest’,
total: 0,
hasMore: false,
busy: false
};

const list = widget.querySelector(‘[data-role=”list”]’);
const loading = widget.querySelector(‘[data-role=”loading”]’);
const empty = widget.querySelector(‘[data-role=”empty”]’);
const loadMoreBtn = widget.querySelector(‘[data-role=”load-more”]’);
const sortSelect = widget.querySelector(‘[data-role=”sort”]’);
const composerForm = widget.querySelector(‘[data-role=”composer-form”]’);

async function loadComments(reset = true) {
if (state.busy) return;

state.busy = true;
setNotice(widget, ”);
loading.hidden = false;

if (reset) {
state.page = 1;
list.innerHTML = ”;
empty.hidden = true;
}

try {
const url = new URL(state.loadUrl, window.location.origin);
url.searchParams.set(‘page’, state.page);
url.searchParams.set(‘per_page’, state.perPage);
url.searchParams.set(‘sort’, state.sort);

const response = await requestJson(url.toString(), {
method: ‘GET’,
headers: {
‘Accept’: ‘application/json’,
‘X-Requested-With’: ‘XMLHttpRequest’
}
});

const items = Array.isArray(response.data) ? response.data : [];
const meta = response.meta || {};

state.total = Number(meta.total || 0);
state.hasMore = !!meta.has_more;

setCount(widget, state.total);

if (reset) {
list.innerHTML = ”;
}

if (!items.length && reset) {
empty.hidden = false;
} else {
empty.hidden = true;
list.insertAdjacentHTML(
‘beforeend’,
items.map(item => commentMarkup(item, state.canComment, false)).join(”)
);
}

loadMoreBtn.hidden = !state.hasMore;
} catch (error) {
if (!list.children.length) {
empty.hidden = false;
empty.textContent = ‘Unable to load comments right now.’;
}
setNotice(widget, error.message || ‘Unable to load comments.’, ‘error’);
} finally {
loading.hidden = true;
state.busy = false;
}
}

async function submitTopLevelComment(form) {
const textarea = form.querySelector(‘textarea[name=”content”]’);
const button = form.querySelector(‘[data-role=”submit-comment”]’);

if (!textarea) return;

const content = textarea.value.trim();
if (!content) return;

const originalText = button ? button.textContent : ”;

try {
if (button) {
button.disabled = true;
button.textContent = ‘Posting…’;
}

const response = await requestJson(state.storeUrl, {
method: ‘POST’,
headers: buildJsonHeaders(),
body: JSON.stringify({
article_id: state.articleId,
content: content,
source_url: window.location.href
})
});

textarea.value = ”;

if (response?.data) {
list.insertAdjacentHTML(
‘afterbegin’,
commentMarkup(response.data, state.canComment, false)
);
empty.hidden = true;

if ((response.data.status || ”) === ‘approved’) {
state.total += 1;
setCount(widget, state.total);
}
}

setNotice(widget, response.message || ‘Comment posted successfully.’);
} catch (error) {
setNotice(widget, error.message || ‘Unable to post comment.’, ‘error’);
} finally {
if (button) {
button.disabled = false;
button.textContent = originalText || ‘Post comment’;
}
}
}

async function submitReply(form) {
const commentId = Number(form.dataset.commentId || 0);
const textarea = form.querySelector(‘textarea[name=”content”]’);
const button = form.querySelector(‘.ev-comments__reply-submit’);

if (!commentId || !textarea) return;

const content = textarea.value.trim();
if (!content) return;

const originalText = button ? button.textContent : ”;

try {
if (button) {
button.disabled = true;
button.textContent = ‘Posting…’;
}

const response = await requestJson(`${state.commentsBaseUrl}/${commentId}/reply`, {
method: ‘POST’,
headers: buildJsonHeaders(),
body: JSON.stringify({
article_id: state.articleId,
content: content,
source_url: window.location.href
})
});

if (response?.data) {
const parentItem = widget.querySelector(`.ev-comments__item[data-comment-id=”${commentId}”]`);
if (parentItem) {
const repliesWrap = parentItem.querySelector(‘.ev-comments__replies’);
if (repliesWrap) {
repliesWrap.insertAdjacentHTML(
‘beforeend’,
commentMarkup(response.data, state.canComment, true)
);
}
}
}

closeReplyBox(form.closest(‘[data-role=”reply-box”]’));
setNotice(widget, response.message || ‘Reply posted successfully.’);
} catch (error) {
setNotice(widget, error.message || ‘Unable to post reply.’, ‘error’);
} finally {
if (button) {
button.disabled = false;
button.textContent = originalText || ‘Post reply’;
}
}
}

async function toggleLike(button) {
const commentId = Number(button.dataset.commentId || 0);
if (!commentId) return;

const originalHtml = button.innerHTML;

try {
button.disabled = true;
button.innerHTML = ‘Working…’;

const response = await requestJson(`${state.commentsBaseUrl}/${commentId}/like`, {
method: ‘POST’,
headers: buildJsonHeaders(),
body: JSON.stringify({})
});

const liked = !!response?.data?.liked;
const likeCount = Number(response?.data?.like_count || 0);

button.classList.toggle(‘is-liked’, liked);
button.innerHTML = `${liked ? ‘Liked’ : ‘Like’} ${likeCount > 0 ? “ : ”}`;
} catch (error) {
button.innerHTML = originalHtml;
setNotice(widget, error.message || ‘Unable to update like.’, ‘error’);
} finally {
button.disabled = false;
}
}

if (composerForm) {
composerForm.addEventListener(‘submit’, function (e) {
e.preventDefault();
submitTopLevelComment(composerForm);
});
}

if (sortSelect) {
sortSelect.addEventListener(‘change’, function () {
state.sort = this.value || ‘newest’;
loadComments(true);
});
}

if (loadMoreBtn) {
loadMoreBtn.addEventListener(‘click’, function () {
if (state.busy || !state.hasMore) return;
state.page += 1;
loadComments(false);
});
}

widget.addEventListener(‘click’, function (e) {
const likeBtn = e.target.closest(‘[data-action=”toggle-like”]’);
if (likeBtn) {
e.preventDefault();
toggleLike(likeBtn);
return;
}

const replyBtn = e.target.closest(‘[data-action=”toggle-reply”]’);
if (replyBtn) {
e.preventDefault();
openReplyBox(widget, Number(replyBtn.dataset.commentId || 0));
return;
}

const cancelReplyBtn = e.target.closest(‘[data-action=”cancel-reply”]’);
if (cancelReplyBtn) {
e.preventDefault();
closeReplyBox(cancelReplyBtn.closest(‘[data-role=”reply-box”]’));
}
});

widget.addEventListener(‘submit’, function (e) {
const replyForm = e.target.closest(‘.ev-comments__reply-form’);
if (replyForm) {
e.preventDefault();
submitReply(replyForm);
}
});

loadComments(true);
}

document.addEventListener(‘DOMContentLoaded’, function () {
document.querySelectorAll(‘.ev-comments’).forEach(initCommentsWidget);
});
})();

Source: eastleighvoice.co.ke

Hot this week

semi final world cup 2026

Trending with 5000+ searches

argentina vs switzerland world cup 2026

Trending with 500+ searches

live football tv

Trending with 2000+ searches

norway national football team

Trending with 500+ searches

premier league

Trending with 200+ searches

semi final world cup 2026

Trending with 5000+ searches

argentina vs switzerland world cup 2026

Trending with 500+ searches

live football tv

Trending with 2000+ searches

norway national football team

Trending with 500+ searches

premier league

Trending with 200+ searches

world cup games

Trending with 100+ searches

france vs morocco world cup 2026

Trending with 100+ searches

today world cup match

Trending with 2000+ searches

Related Articles

Popular Categories