Basic search outline config UI implemented.
This commit is contained in:
@@ -8,255 +8,298 @@
|
||||
ViewData["Specific"] = "Search";
|
||||
}
|
||||
|
||||
<form method="GET">
|
||||
<div class="mt-4 mb-3 less-concise mx-auto">
|
||||
<div class="flex-grow-1 d-flex flex-column" x-data="search">
|
||||
<div class="mt-4 mb-3 less-concise">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control border-primary" placeholder="What are you looking for?"
|
||||
aria-label="Search" aria-describedby="search-btn" id="search-bar" value="@Model.SearchQuery" name="q">
|
||||
aria-label="Search" aria-describedby="search-btn" id="search-bar" value="@Model.SearchQuery"
|
||||
x-model="query">
|
||||
<button class="btn btn-outline-secondary" type="button" id="configuration-toggle" data-bs-toggle="collapse"
|
||||
data-bs-target="#configuration"><i class="bi bi-sliders"></i></button>
|
||||
<button class="btn btn-primary" type="submit" id="search-btn">Search</button>
|
||||
<button class="btn btn-primary" id="search-btn" x-on:click="submitSearch" x-on:keyup="">Search</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="collapse tear" id="configuration">
|
||||
<div class="container my-3">
|
||||
<div class="d-flex">
|
||||
<h1 class="my-2 display-2 me-auto">Configuration</h1>
|
||||
<button class="btn align-self-start" type="button" id="configuration-close" data-bs-toggle="collapse"
|
||||
data-bs-target="#configuration"><i class="bi bi-x-lg"></i></button>
|
||||
</div>
|
||||
<div class="row justify-content-md-center">
|
||||
<section class="col-lg px-4">
|
||||
<h3>Price</h3>
|
||||
<div class="mb-3">
|
||||
<label for="max-price" class="form-label">Maximum Price</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-text">
|
||||
<input class="form-check-input mt-0" type="checkbox" id="max-price-enabled"
|
||||
checked="@Model.ActiveSearchOutline.Filters.EnableUpperPrice"
|
||||
name="ActiveSearchOutline.Filters.EnableUpperPrice">
|
||||
</div>
|
||||
<span class="input-group-text">$</span>
|
||||
<input type="number" class="form-control" min="0" id="max-price"
|
||||
value="@Model.ActiveSearchOutline.Filters.UpperPrice"
|
||||
name="ActiveSearchOutline.Filters.UpperPrice">
|
||||
<span class="input-group-text">.00</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="min-price" class="form-label">Minimum Price</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">$</span>
|
||||
<input type="number" class="form-control" min="0" id="min-price"
|
||||
value="@Model.ActiveSearchOutline.Filters.LowerPrice"
|
||||
name="ActiveSearchOutline.Filters.LowerPrice">
|
||||
<span class="input-group-text">.00</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="max-shipping" class="form-label">Maximum Shipping Fee</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-text">
|
||||
<input class="form-check-input mt-0" type="checkbox" id="max-shipping-enabled"
|
||||
checked="@Model.ActiveSearchOutline.Filters.EnableMaxShippingFee"
|
||||
name="ActiveSearchOutline.Filters.EnableMaxShippingFee">
|
||||
</div>
|
||||
<span class="input-group-text">$</span>
|
||||
<input type="number" class="form-control" min="0" id="max-shipping"
|
||||
value="@Model.ActiveSearchOutline.Filters.MaxShippingFee"
|
||||
name="ActiveSearchOutline.Filters.MaxShippingFee">
|
||||
<span class="input-group-text">.00</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="keep-unknown-shipping"
|
||||
checked="@Model.ActiveSearchOutline.Filters.KeepUnknownShipping"
|
||||
name="ActiveSearchOutline.Filters.KeepUnknownShipping">
|
||||
<label class="form-check-label" for="keep-unknown-shipping">Keep Unknown Shipping</label>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="col-lg px-4">
|
||||
<h3>Metrics</h3>
|
||||
<div class="mb-3">
|
||||
<label for="min-purchases" class="form-label">Minimum Purchases</label>
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" min="0" id="min-purchases"
|
||||
value="@Model.ActiveSearchOutline.Filters.MinPurchases"
|
||||
name="ActiveSearchOutline.Filters.MinPurchases">
|
||||
<span class="input-group-text">Purchases</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="keep-unknown-purchases"
|
||||
checked="@Model.ActiveSearchOutline.Filters.KeepUnknownPurchaseCount"
|
||||
name="ActiveSearchOutline.Filters.KeepUnknownPurchaseCount">
|
||||
<label class="form-check-label" for="keep-unknown-purchases">Keep Unknown Purchases</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="min-reviews" class="form-label">Minimum Reviews</label>
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" min="0" id="min-reviews"
|
||||
value="@Model.ActiveSearchOutline.Filters.MinReviews"
|
||||
name="ActiveSearchOutline.Filters.MinReviews">
|
||||
<span class="input-group-text">Reviews</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="keep-unknown-reviews"
|
||||
checked="@Model.ActiveSearchOutline.Filters.KeepUnknownReviewCount"
|
||||
name="ActiveSearchOutline.Filters.KeepUnknownReviewCount">
|
||||
<label class="form-check-label" for="keep-unknown-reviews">Keep Unknown Number of
|
||||
Reviews</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-1">
|
||||
<label for="min-rating" class="form-label">Minimum Rating</label>
|
||||
<input type="range" class="form-range" id="min-rating" min="0" max="100" step="1"
|
||||
value="@Model.ActiveSearchOutline.Filters.MinRating"
|
||||
name="ActiveSearchOutline.Filters.MinRating">
|
||||
<div id="min-rating-display" class="form-text"></div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="keep-unrated"
|
||||
checked="@Model.ActiveSearchOutline.Filters.KeepUnrated"
|
||||
name="ActiveSearchOutline.Filters.KeepUnrated">
|
||||
<label class="form-check-label" for="keep-unrated">Keep Unrated Items</label>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="col-lg px-4">
|
||||
<h3>Shops Enabled</h3>
|
||||
<div class="mb-3 px-3" id="shop-checkboxes">
|
||||
@foreach (string shopName in Model.SearchManager.ShopManager.GetAllShopNames())
|
||||
{
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="@($"{shopName}-enabled")"
|
||||
checked="@Model.ActiveSearchOutline.Enabled[shopName]">
|
||||
<label class="form-check-label" for="@($"{shopName}-enabled")">@shopName</label>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="d-flex">
|
||||
<h1 class="my-3 display-2 mx-auto">
|
||||
<i class="bi bi-sliders"></i>
|
||||
Configuration
|
||||
</h1>
|
||||
<button class="btn align-self-start m-3" type="button" id="configuration-close" data-bs-toggle="collapse"
|
||||
data-bs-target="#configuration"><i class="bi bi-x-lg"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div id="content-pages" class="multipage mt-3 invisible">
|
||||
<ul class="nav nav-pills selectors">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button type="button" data-bs-toggle="pill" data-bs-target="#quick-picks-slide"><i
|
||||
class="bi bi-stopwatch"></i></button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button type="button" data-bs-toggle="pill" data-bs-target="#results-slide"><i
|
||||
class="bi bi-view-list"></i></button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button type="button" data-bs-toggle="pill" data-bs-target="#info-slide"><i
|
||||
class="bi bi-info-lg"></i></button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="multipage-slides tab-content">
|
||||
<div class="multipage-slide tab-pane fade" id="quick-picks-slide">
|
||||
<div class="multipage-title">
|
||||
<h1 class="display-2"><i class="bi bi-stopwatch"></i> Quick Picks</h1>
|
||||
@if (Model.SearchResults != null)
|
||||
{
|
||||
<p>@ContentManager.Json.quickPicks.searched</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p>@ContentManager.Json.quickPicks.prompt</p>
|
||||
}
|
||||
<hr class="less-concise">
|
||||
</div>
|
||||
<div class="multipage-content">
|
||||
@if (Model.SearchResults != null)
|
||||
{
|
||||
@if (Model.BestRatingPriceRatio != null)
|
||||
{
|
||||
<p>We found this product to have the best rating to price ratio.</p>
|
||||
}
|
||||
|
||||
@if (Model.TopRated != null)
|
||||
{
|
||||
<p>This listing was the one that had the highest rating.</p>
|
||||
}
|
||||
|
||||
@if (Model.MostPurchases != null)
|
||||
{
|
||||
<p>This listing has the most purchases.</p>
|
||||
}
|
||||
|
||||
@if (Model.MostReviews != null)
|
||||
{
|
||||
<p>This listing had the most reviews.</p>
|
||||
}
|
||||
|
||||
@if (Model.BestPrice != null)
|
||||
{
|
||||
<p>Here's the listing with the lowest price.</p>
|
||||
<div>
|
||||
@Model.BestPrice.Name
|
||||
<div class="container">
|
||||
<div class="row my-3">
|
||||
<div class="col-lg-3 px-2">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>Search Outlines</h3>
|
||||
</div>
|
||||
<div class="col-auto" x-show="loggedIn">
|
||||
<button class="btn" x-show="!creatingSearchOutline"
|
||||
x-on:click="createSearchOutlineWithGeneratedName"
|
||||
x-bind:disabled="creatingSearchOutline">
|
||||
<i class="bi bi-plus-lg"></i>
|
||||
</button>
|
||||
<div x-show="creatingSearchOutline" class="spinner-border me-2" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@* TODO: Add display for top results. *@
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="text-center less-concise text-muted flex-grow-1 justify-content-center d-flex flex-column">
|
||||
<h2>@ContentManager.Json.notSearched</h2>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="multipage-slide tab-pane fade" id="results-slide" x-data>
|
||||
<div class="multipage-title">
|
||||
<h2><i class="bi bi-view-list"></i> Results</h2>
|
||||
@if (Model.SearchResults != null)
|
||||
{
|
||||
<p>@ContentManager.Json.results.searched</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p>@ContentManager.Json.results.prompt</p>
|
||||
}
|
||||
<hr class="less-concise">
|
||||
</div>
|
||||
<div class="multipage-content">
|
||||
@if (Model.SearchResults != null)
|
||||
{
|
||||
@* TODO: Display results with UI for sorting and changing views. *@
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="text-center less-concise text-muted flex-grow-1 justify-content-center d-flex flex-column">
|
||||
<h2>@ContentManager.Json.notSearched</h2>
|
||||
<div class="row px-3">
|
||||
<div style="max-height: 28em;" data-simplebar>
|
||||
<template x-for="(current, i) in searchOutlines">
|
||||
<div class="clean-radio d-flex">
|
||||
<input type="radio" x-bind:id="`${i}-selector`" name="search-outline"
|
||||
x-bind:value="i" x-model="selectedSearchOutline"
|
||||
x-on:click="loadSearchOutline(current)" x-bind:disabled="!searchOutline.ready">
|
||||
<label class="flex-grow-1" x-bind:for="`${i}-selector`">
|
||||
<span class="me-auto" x-text="current"></span>
|
||||
</label>
|
||||
<button class="btn m-1" x-show="loggedIn" x-on:click="deleteSearchOutline(current)"
|
||||
x-bind:disabled="deletingSearchOutline || (searchOutlines.length < 2)">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<div class="text-muted text-center my-3" x-show="!loggedIn">
|
||||
<h3><i class="bi bi-box-arrow-in-right"></i></h3>
|
||||
<p>This is where all your search outlines will show up. <a asp-area="Identity"
|
||||
asp-page="/Account/Login">Sign in</a> to create search outlines!</p>
|
||||
</div>
|
||||
<template x-if="(searchOutlines.length < 2) && (loggedIn)">
|
||||
<div class="text-muted text-center my-3 p-3">
|
||||
<p>Add more search outlines by clicking the <i class="bi bi-plus-lg"></i> above!</p>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg px-4">
|
||||
<div class="row">
|
||||
<input class="title-input less-concise mx-4"
|
||||
x-bind:class="searchOutline.ready ? '' : 'invisible'" type="text"
|
||||
x-model="searchOutlines[selectedSearchOutline]" x-on:change="SearchOutlineNameChange"
|
||||
x-bind:disabled="(!loggedIn) || (changingName)">
|
||||
</div>
|
||||
<div class="row justify-content-md-center" x-bind:class="searchOutline.ready ? '' : 'invisible'">
|
||||
<section class="col-md px-3">
|
||||
<h3>Price</h3>
|
||||
<div class="mb-3">
|
||||
<label for="max-price" class="form-label">Maximum Price</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-text">
|
||||
<input class="form-check-input mt-0" type="checkbox" id="max-price-enabled"
|
||||
x-model="searchOutline.filters.enableUpperPrice"
|
||||
x-on:change="searchOutlineChanged">
|
||||
</div>
|
||||
<span class="input-group-text">$</span>
|
||||
<input type="number" class="form-control" min="0" id="max-price"
|
||||
x-model="searchOutline.filters.upperPrice"
|
||||
x-bind:disabled="!searchOutline.filters.enableUpperPrice"
|
||||
x-on:change="searchOutlineChanged" x-on:input="validateNumericalInputs">
|
||||
<span class="input-group-text">.00</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="min-price" class="form-label">Minimum Price</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">$</span>
|
||||
<input type="number" class="form-control" min="0" id="min-price"
|
||||
x-model="searchOutline.filters.lowerPrice" x-on:change="searchOutlineChanged"
|
||||
x-on:input="validateNumericalInputs">
|
||||
<span class="input-group-text">.00</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="max-shipping" class="form-label">Maximum Shipping Fee</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-text">
|
||||
<input class="form-check-input mt-0" type="checkbox" id="max-shipping-enabled"
|
||||
x-model="searchOutline.filters.enableMaxShipping"
|
||||
x-on:change="searchOutlineChanged">
|
||||
</div>
|
||||
<span class="input-group-text">$</span>
|
||||
<input type="number" class="form-control" min="0" id="max-shipping"
|
||||
x-model="searchOutline.filters.maxShippingFee"
|
||||
x-bind:disabled="!searchOutline.filters.enableMaxShipping"
|
||||
x-on:change="searchOutlineChanged" x-on:input="validateNumericalInputs">
|
||||
<span class="input-group-text">.00</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="keep-unknown-shipping"
|
||||
x-model="searchOutline.filters.keepUnknownShipping"
|
||||
x-on:change="searchOutlineChanged">
|
||||
<label class="form-check-label" for="keep-unknown-shipping">Keep Unknown
|
||||
Shipping</label>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="col-md px-3">
|
||||
<h3>Metrics</h3>
|
||||
<div class="mb-3">
|
||||
<label for="min-purchases" class="form-label">Minimum Purchases</label>
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" min="0" id="min-purchases"
|
||||
x-model="searchOutline.filters.minPurchases" x-on:change="searchOutlineChanged"
|
||||
x-on:input="validateNumericalInputs">
|
||||
<span class="input-group-text">Purchases</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="keep-unknown-purchases"
|
||||
x-model="searchOutline.filters.keepUnknownPurchaseCount"
|
||||
x-on:change="searchOutlineChanged">
|
||||
<label class="form-check-label" for="keep-unknown-purchases">Keep Unknown
|
||||
Purchases</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="min-reviews" class="form-label">Minimum Reviews</label>
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" min="0" id="min-reviews"
|
||||
x-model="searchOutline.filters.minReviews" x-on:change="searchOutlineChanged"
|
||||
x-on:input="validateNumericalInputs">
|
||||
<span class="input-group-text">Reviews</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="keep-unknown-reviews"
|
||||
x-model="searchOutline.filters.keepUnknownReviewCount"
|
||||
x-on:change="searchOutlineChanged">
|
||||
<label class="form-check-label" for="keep-unknown-reviews">Keep Unknown Number
|
||||
of
|
||||
Reviews</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-1">
|
||||
<label for="min-rating" class="form-label">Minimum Rating</label>
|
||||
<input type="range" class="form-range" id="min-rating" min="0" max="100" step="1"
|
||||
x-model="searchOutline.filters.minRating" x-on:change="searchOutlineChanged">
|
||||
<div id="min-rating-display" class="form-text"
|
||||
x-text="searchOutline.filters.minRating + '%'">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="keep-unrated"
|
||||
x-model="searchOutline.filters.keepUnrated" x-on:change="searchOutlineChanged">
|
||||
<label class="form-check-label" for="keep-unrated">Keep Unrated Items</label>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="col-md px-3">
|
||||
<h3>Shops Enabled</h3>
|
||||
<template x-for="shopName in Object.keys(searchOutline.shopToggles)">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value=""
|
||||
x-bind:id="`${encodeURIComponent(shopName)}-enabled`"
|
||||
x-model="searchOutline.shopToggles[shopName]"
|
||||
x-on:change="searchOutlineChanged">
|
||||
<label class="form-check-label"
|
||||
x-bind:for="`${encodeURIComponent(shopName)}-enabled`" x-text="shopName">
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
</section>
|
||||
</div>
|
||||
<div x-show="!searchOutline.ready">
|
||||
<div class="spinner-border center-overlay" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="multipage-slide tab-pane fade" id="info-slide">
|
||||
<div class="multipage-content">
|
||||
<div class="less-concise text-muted flex-grow-1 justify-content-center d-flex flex-column">
|
||||
<h1 class="display-3"><i class="bi bi-info-circle"></i> Get Started!</h1>
|
||||
<ol>
|
||||
@foreach (string instruction in ContentManager.Json.instructions)
|
||||
{
|
||||
<li>@instruction</li>
|
||||
}
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="content-pages" class="multipage mt-3 invisible">
|
||||
<ul class="nav nav-pills selectors">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button type="button" data-bs-toggle="pill" data-bs-target="#quick-picks-slide"><i
|
||||
class="bi bi-stopwatch"></i></button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button type="button" data-bs-toggle="pill" data-bs-target="#results-slide"><i
|
||||
class="bi bi-view-list"></i></button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button type="button" data-bs-toggle="pill" data-bs-target="#info-slide"><i
|
||||
class="bi bi-info-lg"></i></button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="multipage-slides tab-content">
|
||||
<div class="multipage-slide tab-pane fade" id="quick-picks-slide">
|
||||
<div class="multipage-title">
|
||||
<h1 class="display-2"><i class="bi bi-stopwatch"></i> Quick Picks</h1>
|
||||
<template x-if="hasResults()">
|
||||
<p>@ContentManager.Json.quickPicks.searched</p>
|
||||
</template>
|
||||
<template x-if="!hasResults()">
|
||||
<p>@ContentManager.Json.quickPicks.prompt</p>
|
||||
</template>
|
||||
<hr class="less-concise">
|
||||
</div>
|
||||
<div class="multipage-content">
|
||||
<template x-if="hasResults()">
|
||||
<template x-if="results.bestPrice">
|
||||
<p>Here's the listing with the lowest price.</p>
|
||||
<div>
|
||||
@* TODO: Implement best price display here *@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@* TODO: Add display for top results. *@
|
||||
</template>
|
||||
<template x-if="!hasResults()">
|
||||
<div
|
||||
class="text-center less-concise text-muted flex-grow-1 justify-content-center d-flex flex-column">
|
||||
<h2>@ContentManager.Json.notSearched</h2>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="multipage-slide tab-pane fade" id="results-slide" x-data>
|
||||
<div class="multipage-title">
|
||||
<h2><i class="bi bi-view-list"></i> Results</h2>
|
||||
<template x-if="hasResults()">
|
||||
<p>@ContentManager.Json.results.searched</p>
|
||||
</template>
|
||||
<template x-if="!hasResults()">
|
||||
<p>@ContentManager.Json.results.prompt</p>
|
||||
</template>
|
||||
<hr class="less-concise">
|
||||
</div>
|
||||
<div class="multipage-content">
|
||||
<template x-if="hasResults()">
|
||||
@* TODO: Display results with UI for sorting and changing views. *@
|
||||
</template>
|
||||
<template x-if="!hasResults()">
|
||||
<div
|
||||
class="text-center less-concise text-muted flex-grow-1 justify-content-center d-flex flex-column">
|
||||
<h2>@ContentManager.Json.notSearched</h2>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="multipage-slide tab-pane fade" id="info-slide">
|
||||
<div class="multipage-content">
|
||||
<div class="less-concise text-muted flex-grow-1 justify-content-center d-flex flex-column">
|
||||
<h1 class="display-3"><i class="bi bi-info-circle"></i> Get Started!</h1>
|
||||
<ol>
|
||||
@foreach (string instruction in ContentManager.Json.instructions)
|
||||
{
|
||||
<li>@instruction</li>
|
||||
}
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
||||
using Castle.Core.Internal;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Props.Data;
|
||||
@@ -21,36 +22,5 @@ namespace Props.Pages
|
||||
{
|
||||
[BindProperty(Name = "q", SupportsGet = true)]
|
||||
public string SearchQuery { get; set; }
|
||||
public IEnumerable<ProductListing> SearchResults { get; private set; }
|
||||
public ProductListing BestRatingPriceRatio { get; private set; }
|
||||
public ProductListing TopRated { get; private set; }
|
||||
public ProductListing MostPurchases { get; private set; }
|
||||
public ProductListing MostReviews { get; private set; }
|
||||
public ProductListing BestPrice { get; private set; }
|
||||
|
||||
public ISearchManager SearchManager { get; private set; }
|
||||
private UserManager<ApplicationUser> userManager;
|
||||
private IMetricsManager analytics;
|
||||
public SearchOutline ActiveSearchOutline { get; private set; }
|
||||
|
||||
public SearchModel(ISearchManager searchManager, UserManager<ApplicationUser> userManager, IMetricsManager analyticsManager)
|
||||
{
|
||||
this.SearchManager = searchManager;
|
||||
this.userManager = userManager;
|
||||
this.analytics = analyticsManager;
|
||||
}
|
||||
|
||||
public async Task OnGetAsync()
|
||||
{
|
||||
ActiveSearchOutline = User.Identity.IsAuthenticated ? (await userManager.GetUserAsync(User)).searchOutlinePreferences.ActiveSearchOutline : new SearchOutline();
|
||||
if (string.IsNullOrWhiteSpace(SearchQuery)) return;
|
||||
Console.WriteLine(SearchQuery);
|
||||
this.SearchResults = await SearchManager.Search(SearchQuery, ActiveSearchOutline);
|
||||
BestRatingPriceRatio = (from result in SearchResults orderby result.GetRatingToPriceRatio() descending select result).FirstOrDefault((listing) => listing.GetRatingToPriceRatio() >= 0.5f);
|
||||
TopRated = (from result in SearchResults orderby result.Rating descending select result).FirstOrDefault();
|
||||
MostPurchases = (from result in SearchResults orderby result.PurchaseCount descending select result).FirstOrDefault();
|
||||
MostReviews = (from result in SearchResults orderby result.ReviewCount descending select result).FirstOrDefault();
|
||||
BestPrice = (from result in SearchResults orderby result.UpperPrice descending select result).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user