-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
930 additions
and
29 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains 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 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 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,29 @@ | ||
import { useState } from "react"; | ||
import Select from "react-select"; | ||
|
||
const options = [ | ||
{ value: "Taylor's gifts", label: "Taylor's gifts" }, | ||
{ value: "Harry's gifts", label: "Harry's gifts" }, | ||
]; | ||
|
||
export type SelectValueType = { | ||
[key: string]: string; | ||
} | null; | ||
|
||
export default function CollectionSelector() { | ||
const [selectedOption, setSelectedOption] = useState<SelectValueType>(null); | ||
|
||
const handleOption = (selection: SelectValueType) => { | ||
setSelectedOption(selection); | ||
}; | ||
|
||
return ( | ||
<div className="App"> | ||
<Select | ||
defaultValue={selectedOption} | ||
onChange={handleOption} | ||
options={options} | ||
/> | ||
</div> | ||
); | ||
} |
This file contains 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,15 @@ | ||
import React from "react"; | ||
import { Gift } from "../types"; | ||
|
||
const Gift: React.FC<Gift> = ({ Name, Link }: Gift) => { | ||
return ( | ||
<div> | ||
<p className="">{Name}</p> | ||
<a className="text-blue-800" href={Link} target="_blank" rel="noreferrer"> | ||
View product | ||
</a> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Gift; |
This file contains 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,51 @@ | ||
import React, { useState } from "react"; | ||
import ResponseCard from "./ResponseCard"; | ||
import ResponseForm from "./ResponseForm"; | ||
import { GiftRequest } from "../types"; | ||
|
||
const RequestCard: React.FC<GiftRequest> = ({ | ||
RecipientName, | ||
RecipientAge, | ||
RecipientInterests, | ||
BudgetMin, | ||
BudgetMax, | ||
GiftResponse, | ||
DateNeeded, | ||
}: GiftRequest) => { | ||
const [showForm, setShowForm] = useState(false); | ||
|
||
return ( | ||
<div className="flex flex-col w-full"> | ||
<h2 className="font-bold text-lg"> | ||
{RecipientName} ({DateNeeded.toDateString()}) | ||
</h2> | ||
<div key={RecipientName} className="px-4 py-2 bg-slate-100"> | ||
<p>Recipient: {RecipientName}</p> | ||
{!GiftResponse && ( | ||
<div> | ||
<p>Recipient age: {RecipientAge}</p> | ||
<p>Recipient interests: {RecipientInterests.join(", ")}</p> | ||
<p> | ||
Budget: ${BudgetMin} - ${BudgetMax} | ||
</p> | ||
<p>Needed by: {DateNeeded.toDateString()}</p> | ||
</div> | ||
)} | ||
</div> | ||
<div> | ||
{GiftResponse && <ResponseCard {...GiftResponse} />} | ||
{!GiftResponse && !showForm && ( | ||
<button | ||
className="bg-blue-600 px-4 py-2 text-white rounded-md mt-4" | ||
onClick={() => setShowForm(true)} | ||
> | ||
Add response | ||
</button> | ||
)} | ||
{showForm && <ResponseForm />} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default RequestCard |
This file contains 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,26 @@ | ||
import React from "react"; | ||
import Gift from "./Gift"; | ||
import { GiftResponse } from "../types"; | ||
|
||
const ResponseCard: React.FC<GiftResponse> = ({ | ||
GiftCollection, | ||
CustomMessage, | ||
}: GiftResponse) => { | ||
return ( | ||
<div className="flex flex-col bg-slate-100 px-4 py-2"> | ||
<h2 className="font-bold text-md">Response:</h2> | ||
<p>{CustomMessage}</p> | ||
<div> | ||
{GiftCollection.Gifts.map((gift) => { | ||
return ( | ||
<div className="mt-2"> | ||
<Gift {...gift} /> | ||
</div> | ||
); | ||
})} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default ResponseCard; |
This file contains 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,27 @@ | ||
import CollectionSelector from "./CollectionSelector"; | ||
|
||
const ResponseForm = () => { | ||
return ( | ||
<div className="flex flex-col justify-between h-full mt-4"> | ||
<div> | ||
<label className="block text-gray-700 text-sm font-bold mb-2"> | ||
Select a gift collection: | ||
<CollectionSelector /> | ||
</label> | ||
<label className="block text-gray-700 text-sm font-bold mb-2"> | ||
Custom message: | ||
<input | ||
className="border rounded w-full py-2 px-3 text-gray-700" | ||
name="message" | ||
type="text" | ||
/> | ||
</label> | ||
</div> | ||
<button className="bg-blue-600 ml-8 px-4 py-2 h-10 text-white rounded-md self-end"> | ||
Submit | ||
</button> | ||
</div> | ||
); | ||
}; | ||
|
||
export default ResponseForm; |
This file contains 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,54 @@ | ||
import RequestCard from "../components/RequestCard"; | ||
import { completeRequests, incompleteRequests } from "./mockData"; | ||
import { useState } from "react"; | ||
import Select from "react-select"; | ||
|
||
export type SelectValueType = { | ||
[key: string]: string; | ||
} | null; | ||
|
||
const options = [ | ||
{ value: "0", label: "Incomplete requests" }, | ||
{ value: "1", label: "Complete requests" }, | ||
{ value: "2", label: "All requests" }, | ||
]; | ||
|
||
export default function RequestsPage() { | ||
const [selectedOption, setSelectedOption] = useState<SelectValueType>({ | ||
value: "2", | ||
label: "All requests", | ||
}); | ||
|
||
const handleOption = (selection: SelectValueType) => { | ||
setSelectedOption(selection); | ||
}; | ||
return ( | ||
<div className="flex flex-col px-96 py-8"> | ||
<h2 className="font-bold text-xl">View gift requests</h2> | ||
<p>Filter gift requests using the dropdown below. </p> | ||
<Select | ||
defaultValue={selectedOption} | ||
onChange={handleOption} | ||
options={options} | ||
/> | ||
{(selectedOption?.value == "0" || selectedOption?.value == "2") && ( | ||
<div className="mt-6"> | ||
<h2 className="font-bold text-xl text-blue-800"> | ||
Incomplete requests | ||
</h2> | ||
{incompleteRequests.map((req) => { | ||
return <RequestCard {...req} />; | ||
})} | ||
</div> | ||
)} | ||
{(selectedOption?.value == "1" || selectedOption?.value == "2") && ( | ||
<div className="mt-6"> | ||
<h2 className="font-bold text-xl text-blue-800">Complete requests</h2> | ||
{completeRequests.map((req) => { | ||
return <RequestCard {...req} />; | ||
})} | ||
</div> | ||
)} | ||
</div> | ||
); | ||
} |
This file contains 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,133 @@ | ||
import { GiftRequest } from "../types"; | ||
|
||
export const completeRequests: GiftRequest[] = [ | ||
{ | ||
CustomerId: 1, | ||
GiftResponseId: null, | ||
RecipientName: "Alice", | ||
RecipientAge: 25, | ||
Occasion: ["Birthday", "Anniversary"], | ||
RecipientInterests: ["Reading", "Traveling"], | ||
BudgetMax: 100, | ||
BudgetMin: 50, | ||
GiftResponse: { | ||
GiftCollection: { | ||
CustomerId: 1, | ||
Customer: { UserId: 1 }, | ||
CollectionName: "Books", | ||
Gifts: [ | ||
{ | ||
Name: "The Catcher in the Rye", | ||
Price: 20, | ||
Link: "https://book-link", | ||
Description: "Classic novel", | ||
Demographic: "Adult", | ||
GiftCollections: [], | ||
}, | ||
{ | ||
Name: "To Kill a Mockingbird", | ||
Price: 15, | ||
Link: "https://book-link", | ||
Description: "Classic novel", | ||
Demographic: "Adult", | ||
GiftCollections: [], | ||
}, | ||
], | ||
}, | ||
GiftCollectionId: 1, | ||
CustomMessage: "Happy Birthday!", | ||
}, | ||
DateNeeded: new Date("2023-01-15"), | ||
}, | ||
{ | ||
CustomerId: 2, | ||
GiftResponseId: null, | ||
RecipientName: "Bob", | ||
RecipientAge: 30, | ||
Occasion: ["Christmas"], | ||
RecipientInterests: ["Music", "Sports"], | ||
BudgetMax: 150, | ||
BudgetMin: 100, | ||
GiftResponse: { | ||
GiftCollection: { | ||
CustomerId: 2, | ||
Customer: { UserId: 2 }, | ||
CollectionName: "Tech Gadgets", | ||
Gifts: [ | ||
{ | ||
Name: "Wireless Headphones", | ||
Price: 80, | ||
Link: "https://headphones-link", | ||
Description: "High-quality sound", | ||
Demographic: "Adult", | ||
GiftCollections: [], | ||
}, | ||
{ | ||
Name: "Smartwatch", | ||
Price: 120, | ||
Link: "https://smartwatch-link", | ||
Description: "Fitness tracking and notifications", | ||
Demographic: "Adult", | ||
GiftCollections: [], | ||
}, | ||
], | ||
}, | ||
GiftCollectionId: 2, | ||
CustomMessage: "Merry Christmas!", | ||
}, | ||
DateNeeded: new Date("2023-12-25"), | ||
}, | ||
{ | ||
CustomerId: 3, | ||
GiftResponseId: null, | ||
RecipientName: "Charlie", | ||
RecipientAge: 22, | ||
Occasion: ["Graduation"], | ||
RecipientInterests: ["Art", "Movies"], | ||
BudgetMax: 80, | ||
BudgetMin: 50, | ||
GiftResponse: { | ||
GiftCollection: { | ||
CustomerId: 3, | ||
Customer: { UserId: 3 }, | ||
CollectionName: "Art Supplies", | ||
Gifts: [ | ||
{ | ||
Name: "Acrylic Paint Set", | ||
Price: 30, | ||
Link: "https://paint-set-link", | ||
Description: "High-quality pigments", | ||
Demographic: "Young Adult", | ||
GiftCollections: [], | ||
}, | ||
{ | ||
Name: "Sketchbook", | ||
Price: 20, | ||
Link: "https://sketchbook-link", | ||
Description: "Blank pages for creative ideas", | ||
Demographic: "Young Adult", | ||
GiftCollections: [], | ||
}, | ||
], | ||
}, | ||
GiftCollectionId: 3, | ||
CustomMessage: "Congratulations on your graduation!", | ||
}, | ||
DateNeeded: new Date("2023-05-20"), | ||
}, | ||
]; | ||
|
||
export const incompleteRequests: GiftRequest[] = [ | ||
{ | ||
CustomerId: 3, | ||
GiftResponseId: null, | ||
RecipientName: "Charlie", | ||
RecipientAge: 22, | ||
Occasion: ["Graduation"], | ||
RecipientInterests: ["Art", "Movies"], | ||
BudgetMax: 80, | ||
BudgetMin: 50, | ||
GiftResponse: null, | ||
DateNeeded: new Date("2023-05-20"), | ||
}, | ||
]; |
Oops, something went wrong.