-
Notifications
You must be signed in to change notification settings - Fork 37
Search menu & mertic cards plan #3
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
Open
Nick040791
wants to merge
23
commits into
LaunchCodeEducation:main
Choose a base branch
from
Nick040791:search-menu-&-mertic-cards-plan
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
7c91a34
Verify installs and create folder structure
Nick040791 6ae3eeb
Routes added
Nick040791 09c6738
created context components
Nick040791 1ba6083
imported search context into useSearch
Nick040791 9b7d38d
update main.jsx and App.jsx
Nick040791 89cfae3
updated main and stats
Nick040791 1d9f025
asd
Nick040791 d01d53d
Search menu logic
Nick040791 325af25
Fixed SearchMenu typo and syntax
Nick040791 bb32d3b
1. Fixed Nav elements in NavBar.jsx
Nick040791 4d8c159
Updated search menu and completed metric cards
Nick040791 7a5b8c9
Update Homepage to use Home component, fixed flaky imports and syntax…
Nick040791 83d9d5c
Finish search results table
Nick040791 e9b0d52
Fixed SearchMenu showing two success messages
Nick040791 54a5ae4
Added search results table component to search page
Nick040791 ba1e37a
fixed lower_keyword storing non lowercase values in routes.js
Nick040791 2c56b8e
Fix routes and no initial state error rendering in useSearch
Nick040791 0a5afd7
stuff
Nick040791 576e03e
Update the server to handle empty initial filtertype value
Nick040791 bce70c0
realized I didn't add metic cards to the SearchPage :/ and added boot…
Nick040791 00ba733
change route path to catch all invalid paths
Nick040791 a9efa98
Spice up 404 and hompage with bootstrap
Nick040791 ef2c10b
fixed metric field key
Nick040791 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| const Home = () => { | ||
| return <section className="container my-5"> | ||
| <div className="card shadow-sm border-0"> | ||
| <div className="card-body p-4 p-md-5"> | ||
| <h1 className="display-5 fw-bold text-primary mb-3">User Behavior Dataset</h1> | ||
| <p className="lead-text-muted">This dataset provides a comprehensive analysis | ||
| of mobile device usage patterns and user behavior classification. It contains 700 samples | ||
| of user data, including metrics such as app usage time, screen-on time, battery drain, and data | ||
| consumption. Each entry is categorized into one of five user behavior classes, ranging from light to | ||
| extreme usage, allowing for insightful analysis and modeling.</p> | ||
|
|
||
| <p className="h-4 fw-semibold mt-4 mb-3">Key Features: </p> | ||
|
|
||
| <ul className="list-group list-group-flush"> | ||
| <li className="list-group-item px-0"><strong>User ID:</strong> Unique identifier for each user.</li> | ||
| <li className="list-group-item px-0"><strong>Device Model:</strong> Model of the user{`'s`} smartphone.</li> | ||
| <li className="list-group-item px-0"><strong>Operating System:</strong> The OS of the device (iOS or Android).</li> | ||
| <li className="list-group-item px-0"><strong>App Usage Time:</strong> Daily time spent on mobile applications, measured in minutes.</li> | ||
| <li className="list-group-item px-0"><strong>Screen On Time:</strong> Average hours per day the screen is active.</li> | ||
| <li className="list-group-item px-0"><strong>Battery Drain:</strong> Daily battery consumption in mAh.</li> | ||
| <li className="list-group-item px-0"><strong>Number of Apps Installed:</strong> Total apps available on the device.</li> | ||
| <li className="list-group-item px-0"><strong>Data Usage:</strong> Daily mobile data consumption in megabytes.</li> | ||
| <li className="list-group-item px-0"><strong>Age:</strong> Age of the user.</li> | ||
| <li className="list-group-item px-0"><strong>Gender:</strong> Gender of the user (Male or Female).</li> | ||
| <li className="list-group-item px-0"><strong>User Behavior Class:</strong> Classification of user behavior based on usage patterns (1 to 5).</li> | ||
| </ul> | ||
| </div> | ||
| </div> | ||
| <div> | ||
| <a href="https://www.kaggle.com/datasets/valakhorasani/mobile-device-usage-and-user-behavior-dataset?resource=download" >Sourced from this Kaggle Dataset</a> | ||
| </div> | ||
| </section> | ||
| }; | ||
|
|
||
| export default Home; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| import { useMemo } from 'react'; | ||
| import { useSearch } from '../hooks/useSearch'; | ||
| import { METRIC_FIELDS } from '../utils/constants'; | ||
| import { average, formatNumber, median } from '../utils/stats'; | ||
|
|
||
| function MetricCards() { | ||
| const { results, status } = useSearch(); | ||
| const metricData = useMemo(() => { | ||
| return METRIC_FIELDS.map((field) => { | ||
| const values = results | ||
| .map((record) => Number(record[field.key])) | ||
| .filter((value) => !Number.isNaN(value)); | ||
|
|
||
| return { | ||
| title: field.title, | ||
| unit: field.unit, | ||
| averageValue: average(values), | ||
| medianValue: median(values), | ||
| }; | ||
| }); | ||
| },[results]) | ||
|
|
||
| if (results.length === 0 && status != 'loading') { | ||
| return ( | ||
| <section className="container py-4"> | ||
| <div className="card text-center text-muted"> | ||
| <div className="card-body"> | ||
| Run a search to see metrics. | ||
| </div> | ||
| </div> | ||
| </section> | ||
| ); | ||
| } | ||
|
|
||
| return ( | ||
| <section className="container py-4"> | ||
| <div className="row row-cols-1 row-col-me-4 g-3"> | ||
| { | ||
| metricData.map((metric) => ( | ||
| <div className="col" key={metric.title}> | ||
| <div className="card h-100 shadow-sm"> | ||
| <div className="card-body"> | ||
| <h2 className="h5 card-title">{metric.title}</h2> | ||
|
|
||
| <p className="card-text mb-1"> | ||
| Average: {formatNumber(metric.averageValue)} {metric.unit} | ||
| </p> | ||
|
|
||
| <p className="card-text mb-0"> | ||
| Median: {formatNumber(metric.medianValue)} {metric.unit} | ||
| </p> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ) | ||
| ) | ||
| } | ||
|
|
||
| </div> | ||
| </section> | ||
| ); | ||
| }; | ||
|
|
||
| export default MetricCards; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| import { NavLink } from "react-router-dom"; | ||
|
|
||
| const Navbar = () => { | ||
| return ( | ||
| <nav className="navbar navbar-expand-lg navbar-dark bg-dark sticky-top"> | ||
| <NavLink to="/" className="navbar-brand ms-4 nav-link">User Behavior Data</NavLink> | ||
| <NavLink to="/Search" className="navbar-brand ms-4 nav-link">Search</NavLink> | ||
| </nav> | ||
|
Nick040791 marked this conversation as resolved.
|
||
| ); | ||
| }; | ||
|
|
||
| export default Navbar; | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import { Link } from "react-router-dom"; | ||
|
|
||
|
|
||
| // The not found component for when stuff is... | ||
|
|
||
| const NotFound = () => { | ||
| return ( | ||
| <section className="container py-5 text-center border border-4 bg-light shadow-sm"> | ||
| <div className="row justify-content-center"> | ||
| <div className="col-md-6"> | ||
| <h1 className="display-1 fw-bold text-danger mb-4">404</h1> | ||
| <h2 className="h-4 mb-3 text-primary">Not Found</h2> | ||
| <p className="text-muted mb-5">This page either does not exist or I broke it somehow :/</p> | ||
| <div className="d-grip gap-2 col-md-4 mx-auto"> | ||
| <p className="text-muted">You don't have to go</p> | ||
| <Link to="/">HOME</Link> | ||
| <p className="text-muted">But you can't stay here</p> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </section> | ||
| ); | ||
| }; | ||
|
|
||
| export default NotFound; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| import { useState } from "react"; | ||
| import { useSearch } from '../hooks/useSearch' | ||
| import { FILTER_TYPE_OPTIONS } from "../utils/constants"; | ||
|
|
||
| /* | ||
| Okay, so the SearchMenu component handles the search menu on the search page. | ||
| I'm trying to grab the search state and helper functions from the search context. | ||
| This is the main search state that the rest of the app will use. | ||
| The 'local state' below the function is just for what the user sees before they hit submit and stuff. | ||
| */ | ||
|
|
||
|
|
||
| function SearchMenu(){ | ||
|
|
||
| const { filterType, setFilterType, keyword, setKeyword, results, status, errorMsg, runSearch, } = useSearch(); | ||
| const[localFilterType, setLocalFilterType] = useState(filterType); | ||
| const[localKeyword, setLocalKeyword] = useState(keyword); | ||
|
|
||
| function handleSubmit(event){ // you're a nested function | ||
| event.preventDefault(); // when we hit the search button, don't do what you normally do | ||
| setFilterType(localFilterType); // instead set the SearchMenu filter type using the local one we just got | ||
| setKeyword(localKeyword); // also do it again but keyword (͡° ͜ʖ ͡°) | ||
|
|
||
| runSearch({ | ||
| filterType: localFilterType, | ||
| keyword: localKeyword, | ||
| }); | ||
| } | ||
|
|
||
|
|
||
|
|
||
| return ( | ||
| <section className="container py-4 text-start"> | ||
| <div className="p-4 bg-light rounded-3 shadow-sm border"> | ||
| <form className="row g-3 align-items-end" onSubmit={handleSubmit}> | ||
|
|
||
| <div className="col-md-3"> | ||
| <label className="form-label" htmlFor="filterType">Filter Type</label> | ||
| <select id="filterType" value={localFilterType} className="form-select" onChange={(event) => setLocalFilterType(event.target.value)}> | ||
| {FILTER_TYPE_OPTIONS.map((option) => (<option value ={option.value} key={option.value || 'all'}> | ||
| {option.label} | ||
| </option>) )} | ||
| </select> | ||
|
Nick040791 marked this conversation as resolved.
|
||
| </div> | ||
|
|
||
| <div className="col-md-6"> | ||
| <label className="form-label" htmlFor="keyword"> | ||
| Keyword | ||
| </label> | ||
| <input id="keyword" className="form-control" type="search" value={localKeyword} onChange={(event) => setLocalKeyword(event.target.value)} placeholder="Enter search keyword" /> | ||
| </div> | ||
|
|
||
| <div className="col-md-3"> | ||
| <button className="btn btn-primary w-100" type="submit" disabled={status === 'loading'}> | ||
| {status === 'loading' ? 'Searching...' : 'Search'} | ||
| </button> | ||
| </div> | ||
|
|
||
| </form> | ||
| </div> | ||
|
|
||
| <div className="mt-3"> | ||
| {status === 'loading' && (<p className="text-muted mb-0">Loading...</p>)} | ||
| {status === 'error' && (<p className="text-danger mb-0">Error: {errorMsg}</p>)} | ||
| {status === 'success' && results.length > 0 && ( | ||
| <p className="text-muted mb-0">Displaying {results.length} Records</p> | ||
| )} | ||
| </div> | ||
| </section> | ||
| ); | ||
| }; | ||
|
|
||
| export default SearchMenu; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| // 🡫 Grab the useSearch hook! 🡫 | ||
| import { useSearch } from "../hooks/useSearch"; | ||
|
|
||
| function SearchResultsTable(){ | ||
|
|
||
| //Put the {fries and stuff} in the bag; | ||
| const { results = [] , status = "loading", errorMsg = "" } = useSearch(); | ||
|
|
||
|
|
||
| // 🡫 Show a loading artifact while fetching and rendering results and stuff 🡫 | ||
| if (status ==="loading"){ | ||
| return ( | ||
| <section className="container py-3"> | ||
| <p className="text-muted">Loading Records...</p> | ||
| </section> | ||
| ); | ||
| }; | ||
|
|
||
| if (results.length === 0) { | ||
| return ( | ||
| <section className="container py-4 text-start"> | ||
| {status === "error" && ( | ||
| <div className="text-danger mb-3">Error: {errorMsg}</div> | ||
| )} | ||
|
|
||
| <p className="text-muted">No Records To Display</p> | ||
| </section> | ||
| ); | ||
| } | ||
|
|
||
| const headers = Object.keys(results[0]); | ||
|
|
||
| return ( | ||
| <section className="container py-4 text-start"> | ||
| {status === "error" && ( | ||
| <div className="text-danger mb-3">Error: {errorMsg}</div> | ||
| )} | ||
|
|
||
| <div className="table-responsive"> | ||
| <table className="table table-striped table-hover text-start"> | ||
| <thead> | ||
| <tr> | ||
| {headers.map((header) => ( | ||
| <th className="text-start" key={header} scope="col"> | ||
| {header} | ||
| </th> | ||
| ))} | ||
| </tr> | ||
| </thead> | ||
|
|
||
| <tbody> | ||
| {results.map((record, index) => ( | ||
| <tr key={record["User ID"] || index}> | ||
| {headers.map((header) => ( | ||
| <td key={header}>{record[header]}</td> | ||
| ))} | ||
| </tr> | ||
| ))} | ||
| </tbody> | ||
| </table> | ||
| </div> | ||
| </section> | ||
| ); | ||
| } | ||
|
|
||
| export default SearchResultsTable; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.