Skip to content

Commit

Permalink
Merged conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
thea2506 committed Mar 2, 2024
2 parents b3d2462 + b3d9457 commit bed6bc0
Show file tree
Hide file tree
Showing 13 changed files with 351 additions and 1 deletion.
17 changes: 16 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ import { createBrowserRouter, RouterProvider } from "react-router-dom";
// routes

import ButtonTestRoute from "@/routes/ButtonTestRoute";

import ProfilePictureTest from "./routes/ProfilePictureTestRoute";
import Test from "./routes/Test";
import SearchBarTest from "./routes/SearchBarTestRoute";
import DropdownItem from "@/components/DropdownItem";
import SortDropdownListTestRoute from "@/routes/SortDropdownListTestRoute";
import NavigationTest from "@/routes/NavigationTest";
import InputCodeTest from "@/routes/InputCodeTest";
import ToastTestRoute from "@/routes/ToastTestRoute";
import MediaUploadZoneTestRoute from "@/routes/MediaUploadZoneTestRoute";

const router = createBrowserRouter([
{
Expand All @@ -19,6 +22,10 @@ const router = createBrowserRouter([
path: "/test",
element: <Test />,
},
{
path: "/SearchBarTestRoute",
element: <SearchBarTest />,
},
{
path: "/testButton",
element: <ButtonTestRoute />,
Expand All @@ -35,6 +42,14 @@ const router = createBrowserRouter([
path: "/input-code-test",
element: <InputCodeTest />,
},
{
path: "/upload-file-test",
element: <MediaUploadZoneTestRoute />,
},
{
path: "/toast-test",
element: <ToastTestRoute />,
},
]);

function App() {
Expand Down
Binary file added src/assets/images/face.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/face1.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/face2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions src/assets/images/profile_pic.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
121 changes: 121 additions & 0 deletions src/components/MediaUploadZone.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { UploadSimple, WarningCircle } from "@phosphor-icons/react";
import { useState, useEffect, useRef } from "react";

interface MediaUploadZoneProps {
onFilesDropped: (files: File[]) => void;
fontSize?: string;
}

const MediaUploadZone: React.FC<MediaUploadZoneProps> = ({
onFilesDropped,
}) => {
// parent ref
const parentRef = useRef<HTMLDivElement>(null);

// handling sizing
// handling drop in file
const [isDragOver, setIsDragOver] = useState(false);
const [droppedFiles, setDroppedFiles] = useState<File[]>([]);
const [isValidFile, setIsValidFile] = useState(true);

const UploadZoneClassName =
"w-full h-full border-2 border-dashed flex flex-col justify-center items-center rounded-md border-primary-main text-base" +
(isDragOver
? " transform transition-transform duration-300 border-primary-dark ease-in-out scale-95"
: "");

// handle drop events, drop the PNG, JPEG and GIF type of file
const handleDrop = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
const files = Array.from(event.dataTransfer.files);
const validFiles = filterValidFiles(files);

setDroppedFiles((prevFiles) => [...prevFiles, ...validFiles]);
setIsDragOver(false);
};

const filterValidFiles = (files: File[]): File[] => {
const allowedExtensions = [".jpg", ".jpeg", ".png", ".gif"];

return files.filter((file) => {
const extension = file.name
.toLowerCase()
.slice(file.name.lastIndexOf("."));
const isValid = allowedExtensions.includes(extension);
isValid ? setIsValidFile(true) : setIsValidFile(false);
console.log(`File ${file.name} is ${isValid ? "valid" : "invalid"}.`);
return isValid;
});
};

const handleDragOver = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
setIsDragOver(true);
};

const handleDragLeave = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
setIsDragOver(false);
};

useEffect(() => {
console.log("Dropped files:", droppedFiles);
}, [droppedFiles]);

return (
<div className="w-full h-full ">
<div
className={UploadZoneClassName}
onDrop={handleDrop}
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
>
<div className="flex flex-col justify-center items-center flex-grow text-body-reg sm:text-body-sm ">
<UploadSimple className="mb-3 leading-normal scale-[2]" />
<div className="leading-normal ">Drag and Drop here</div>
<div className="leading-normal"> or </div>
<input
type="file"
id="fileInput"
onChange={(event) => {
if (event.target.files) {
const files = Array.from(event.target.files);
const validFiles = filterValidFiles(files);
setDroppedFiles((prevFiles) => [...prevFiles, ...validFiles]);
}
}}
className="hidden"
/>
<label
htmlFor="fileInput"
className="text-primary-main cursor-pointer leading-normal"
>
Browse file
</label>
</div>
{droppedFiles.length > 0 && (
<div className="truncate w-5/6 flex flex-col items-center overflow-hidden">
{droppedFiles.slice(0, 3).map((file, index) => (
<div key={index} className="truncate w-full text-center">
{file.name}
</div>
))}
{droppedFiles.length > 3 && <div>...</div>}
</div>
)}
</div>
<div className="flex flex-row justify-between text-xs text-gray-500 mt-0.5">
<div>Accepted file types: png, jpeg</div>
<div>Max size: 25MB</div>
</div>
{!isValidFile && (
<div className="flex flex-row text-xs text-red-500">
<WarningCircle className="mt-0.5 mr-0.5"></WarningCircle> File type
not supported
</div>
)}
</div>
);
};

export default MediaUploadZone;
34 changes: 34 additions & 0 deletions src/components/ProfilePictures.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as Icon from '@phosphor-icons/react'
import { ReactNode } from 'react';
//define the prop types for the component
interface Props {
children: ReactNode;
backgroundColor: 'tulip' | 'gold' | 'lime' | 'jade' | 'water' | 'air' | 'lilac' | 'candy';
}


const ProfilePictures=(props:Props)=>{

const backgroundColor= `bg-profile-${props.backgroundColor}`
// return(<div>
// <div className="overflow-hidden justify-center items-center rounded-full w-32 h-32">
// {props.children?
// <img className="object-center w-32 h-32" src={props.children} alt="Profile Pic" />
// :
// <div className={`bg-profile-${props.backgroundColor} flex justify-center items-center rounded-full w-32 h-32`}>
// <Icon.PawPrint size={120} color={'white'} />
// </div>
// }

// </div>

// </div>);

return(<div>
<div className={`bg-profile-${props.backgroundColor} object-fill object-center flex overflow-hidden justify-center items-center rounded-full w-32 h-32`}>
{props.children}
</div>
</div>)
};

export default ProfilePictures;
34 changes: 34 additions & 0 deletions src/components/SearchBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {useState, useRef} from "react";
import { MagnifyingGlass } from "@phosphor-icons/react";

export interface SearchBarProps {
target: string;
}


function SearchBar({ target }: SearchBarProps) {
// const input = useRef<HTMLDivElement>(null);
const [query,setQuery] = useState("")


const handleClick = () => {
//handle query
//redirect to results
console.log(query)
}

return <div className={"h-[2.5em] flex flex-row m-[1em]"}>
<input
value={query}
placeholder={"Search by " + target}
className={"p-[0.5em] rounded-l-lg border w-[20em]"}
onChange={e => setQuery(e.target.value)}
/>
<button className={"rounded-r-lg bg-primary-main p-[0.5em] hover:bg-primary-light cursor-pointer"} onClick={handleClick} >
<MagnifyingGlass color="white" size={"1em"} />
</button>
</div>;
}

export default SearchBar;

58 changes: 58 additions & 0 deletions src/components/Toast.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import clsx from "clsx";
import { Warning, WarningCircle, Check, Info } from "@phosphor-icons/react";


interface ToastIconProps {
/** The theme of the toast */
severity?: "success" | "error" | "warning" | "info" | "neutral",
}

function ToastIcon({ severity }: ToastIconProps) {
if (severity === "success") {
return <Check className="text-status-green-main" size={24}/>;
} else if (severity === "error") {
return <WarningCircle className="text-status-red-main" size={24}/>;
} else if (severity === "warning") {
return <Warning className="text-status-yellow-main" size={24}/>;
} else if (severity === "info") {
return <Info className="text-status-blue-main" size={24}/>;
} else {
return null;
}
}

interface ToastProps {
/** The text to display inside the toast */
message: string,

/** The theme of the toast */
severity?: "success" | "error" | "warning" | "info" | "neutral",
}

function Toast({ message, severity = "neutral" }: ToastProps) {

// Body style
const body = "flex py-2 pl-4 pr-6 rounded gap-2";

// Themes
const success = "bg-status-green-light";
const error = "bg-status-red-light";
const warning = "bg-status-yellow-light";
const info = "bg-status-blue-light";
const neutral = "bg-neutrals-light-300";

return (
<div className={clsx(body, {
[success]: severity === "success",
[error]: severity === "error",
[warning]: severity === "warning",
[info]: severity === "info",
[neutral]: severity === "neutral"
})}>
<ToastIcon severity={ severity }/>
<span className="text-neutrals-dark-500">{ message }</span>
</div>
)
}

export default Toast;
22 changes: 22 additions & 0 deletions src/routes/MediaUploadZoneTestRoute.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from "react";
import MediaUploadZone from "@/components/MediaUploadZone";

const MediaUploadZonetestRoute: React.FC = () => {
const handleFilesDropped = (files: File[]) => {
// handle file
console.log("Dropped files:", files);
};

return (
<div className="w-full h-full flex flex-col">
<div className="grid place-items-center h-screen ">
{/* renember to put it in a parent div that is large enough */}
<div className="w-9/12 h-64 mb-4 ">
<MediaUploadZone onFilesDropped={handleFilesDropped} />
</div>
</div>
</div>
);
};

export default MediaUploadZonetestRoute;
22 changes: 22 additions & 0 deletions src/routes/ProfilePictureTestRoute.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import ProfilePictures from "@/components/ProfilePictures";
import profilePic from "@/assets/images/face2.jpg";
import profilePic1 from "@/assets/images/face1.jpeg";
import profilePic2 from "@/assets/images/face.jpeg";

import * as Icon from '@phosphor-icons/react'

function ProfilePictureTest() {


return (
<div className="space-y-4 p-4">
<ProfilePictures backgroundColor="tulip"><img className="w-full h-full object-cover rounded-full" src={profilePic} alt="Profile pic" /></ProfilePictures>
<ProfilePictures backgroundColor="tulip"><img className="w-full h-full object-cover rounded-full" src={profilePic1} alt="Profile pic" /></ProfilePictures>
<ProfilePictures backgroundColor="tulip"><img className="w-full h-full object-cover rounded-full" src={profilePic2} alt="Profile pic" /></ProfilePictures>

<ProfilePictures backgroundColor="tulip"><Icon.PawPrint className="w-full h-full object-cover rounded-full" size={100} color={'white'}/></ProfilePictures>
</div>
);
}

export default ProfilePictureTest;
12 changes: 12 additions & 0 deletions src/routes/SearchBarTestRoute.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import SearchBar from "../components/SearchBar";

function SearchBarTest() {
return (
<div className="flex flex-col justify-center items-center min-h-screen">
<SearchBar target={"name"} />
<SearchBar target={"photo ID"} />
</div>
);
}

export default SearchBarTest;
16 changes: 16 additions & 0 deletions src/routes/ToastTestRoute.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Toast from "@/components/Toast";

function ToastTestRoute() {
return (
<div className="flex flex-col justify-center gap-4 items-center min-h-screen">
<Toast severity="success" message="This is a success message" />
<Toast severity="error" message="This is an error message" />
<Toast severity="warning" message="This is a warning message" />
<Toast severity="info" message="This is an info message" />
<Toast severity="neutral" message="This is a neutral message"/>
<Toast message="This is a message with no severity" />
</div>
);
}

export default ToastTestRoute;

0 comments on commit bed6bc0

Please sign in to comment.