Kaynağa Gözat

created assignment form validation toast

develop
Ajay_S 3 yıl önce
ebeveyn
işleme
6df5a6df83
10 değiştirilmiş dosya ile 221 ekleme ve 80 silme
  1. +64
    -65
      src/App.tsx
  2. +56
    -0
      src/components/Toast/Toast.module.scss
  3. +48
    -0
      src/components/Toast/Toast.tsx
  4. +14
    -1
      src/components/formInput/Input.tsx
  5. +0
    -1
      src/mockData/QuizDetails.tsx
  6. +1
    -1
      src/pages/assignment/Assignment.module.scss
  7. +2
    -2
      src/pages/assignment/SubmitAssignment.module.scss
  8. +30
    -9
      src/pages/assignment/SubmitAssignment.tsx
  9. +4
    -0
      src/pages/finalInterview/FinalInterview.tsx
  10. +2
    -1
      src/pages/technicalInterview/TechnicalInterview.tsx

+ 64
- 65
src/App.tsx Dosyayı Görüntüle

@@ -1,5 +1,5 @@
import { Redirect, Route } from 'react-router-dom';
import { IonApp, IonRouterOutlet, setupIonicReact } from '@ionic/react';
import { Redirect, Route, Switch } from 'react-router-dom';
import { IonApp, IonItem, IonRouterOutlet, setupIonicReact } from '@ionic/react';
import { IonReactRouter } from '@ionic/react-router';

/* Core CSS required for Ionic components to work properly */
@@ -38,8 +38,6 @@ import JoiningLetter from './pages/joiningLetter/JoiningLetter';
import Celebration from './pages/celebration/Celebration';
import SignaturePhoto from './pages/joiningLetter/SignaturePhoto';
import TechinicalInterviewResults from './pages/technicalInterview/TechinicalInterviewResults';
import CountdownTimer from './components/CountDownTimer/CountdownTimer';



setupIonicReact();
@@ -48,67 +46,68 @@ const App: React.FC = () => (
<IonApp>
<IonReactRouter>
<IonRouterOutlet>
<Route exact path="/interviewRounds">
<InterviewRounds />
</Route>
<Route exact path="/skillInformationStep">
<SkillInformationStep />
</Route>
<Route exact path="/quiz">
<Quiz />
</Route>
<Route exact path="/preliminaryRound">
<PreliminaryRound />
</Route>
<Route exact path="/preliminaryRoundResults">
<PreliminaryRoundResults />
</Route>
<Route exact path="/technicalInterview">
<TechnicalInterview />
</Route>
<Route exact path="/technicalInterview/techinicalInterviewResults">
<TechinicalInterviewResults />
</Route>
<Route exact path="/assignment">
<Assignment />
</Route>
<Route exact path="/assignmentDetails">
<AssignmentDetails />
</Route>
<Route exact path="/SubmitAssignment">
<SubmitAssignment />
</Route>
<Route exact path="/ReviewAssignment">
<ReviewAssignment />
</Route>
<Route exact path="/assignmentCompleted">
<AssignmentCompleted />
</Route>
<Route exact path="/finalInterview">
<FinalInterview />
</Route>
<Route exact path="/finalInterview/results">
<FinalInterviewResult />
</Route>
<Route exact path="/closingDocs">
<ClosingDocs />
</Route>
<Route exact path="/verifiedDocs">
<VerifiedDocs />
</Route>
<Route exact path="/joiningLetter">
<JoiningLetter />
</Route>
<Route exact path="/joiningLetter/signaturePhoto">
<SignaturePhoto />
</Route>
<Route exact path="/celebration">
<Celebration />
</Route>
<Route exact path="/">
<Redirect to="/interviewRounds" />
</Route>

<Switch>
<Route exact path="/interviewRounds">
<InterviewRounds />
</Route>
<Route exact path="/skillInformationStep">
<SkillInformationStep />
</Route>
<Route exact path="/quiz">
<Quiz />
</Route>
<Route exact path="/preliminaryRound">
<PreliminaryRound />
</Route>
<Route exact path="/preliminaryRoundResults">
<PreliminaryRoundResults />
</Route>
<Route exact path="/technicalInterview">
<TechnicalInterview />
</Route>
<Route exact path="/technicalInterview/techinicalInterviewResults">
<TechinicalInterviewResults />
</Route>
<Route exact path="/assignment">
<Assignment />
</Route>
<Route exact path="/assignmentDetails">
<AssignmentDetails />
</Route>
<Route exact path="/SubmitAssignment">
<SubmitAssignment />
</Route>
<Route exact path="/ReviewAssignment">
<ReviewAssignment />
</Route>
<Route exact path="/assignmentCompleted">
<AssignmentCompleted />
</Route>
<Route exact path="/finalInterview">
<FinalInterview />
</Route>
<Route exact path="/finalInterview/results">
<FinalInterviewResult />
</Route>
<Route exact path="/closingDocs">
<ClosingDocs />
</Route>
<Route exact path="/verifiedDocs">
<VerifiedDocs />
</Route>
<Route exact path="/joiningLetter">
<JoiningLetter />
</Route>
<Route exact path="/joiningLetter/signaturePhoto">
<SignaturePhoto />
</Route>
<Route exact path="/celebration">
<Celebration />
</Route>
<Route exact path="/">
<Redirect to="/interviewRounds" />
</Route>
</Switch>
</IonRouterOutlet>
</IonReactRouter>
</IonApp>


+ 56
- 0
src/components/Toast/Toast.module.scss Dosyayı Görüntüle

@@ -0,0 +1,56 @@
.toastContent {
width: 90%;
position: fixed;
bottom:5%;
left: 5%;
z-index: 10;

.toastHolder {
display: flex;
align-items: center;
justify-content: space-between;
border: 0.1rem solid transparent;
border-radius: 2.5rem;
background-color: white;
min-height: 4rem;
.messageHolder {
display: flex;
align-items: center;
margin-left: 1.5rem;

.text {
margin-left: 1rem;
font-size: 1.4rem;
}
}

.closeIcon {
color: #ec0b6d;
min-width: 20px;
height: 20px;
margin-right: 10px;
}

.checkIcon {
width: 20px;
height: 20px;
color: #00ae8d;
}
.errorIcon {
min-width: 20px;
height: 20px;
color: #ea7a7a;
}
}

.error {
box-shadow: 0 0 15px #ea7a7a;
}

.success {
box-shadow: 0 0 15px #00ae8d;
}

}

+ 48
- 0
src/components/Toast/Toast.tsx Dosyayı Görüntüle

@@ -0,0 +1,48 @@
import { IonIcon, IonItem } from "@ionic/react";
import styles from "./Toast.module.scss";
import { checkmarkCircle, closeCircle, alertCircle } from 'ionicons/icons';
import { useEffect, useState } from "react";


interface OwnProps {
message: string;
messageType: string;
showToast: boolean;
}

const Toast: React.FC<OwnProps> = (props) => {

const [showToast, setShowToast] = useState(props.showToast);
console.log("show props", props.showToast);

useEffect(() => {
setShowToast(props.showToast);
}, [props.showToast]);

// const [showToast, setShowToast] = useState(props.showToast);
console.log(showToast)

const closeToast = () => {
setShowToast(false);
}

setTimeout(() => {
closeToast();
}, 3000);



return (
<div className={styles.toastContent}>
{showToast && < div className={styles.toastHolder + " " + styles.error} >
<div className={styles.messageHolder}>
<IonIcon className={styles.errorIcon} icon={alertCircle} />
<div className={styles.text}>invalid Input</div>
</div>
<IonIcon className={styles.closeIcon} icon={closeCircle} />
</div>}
</div >
);
}

export default Toast;

+ 14
- 1
src/components/formInput/Input.tsx Dosyayı Görüntüle

@@ -1,14 +1,26 @@
import styles from './Input.module.scss';
import { IonIcon, IonInput, IonItem, IonLabel } from '@ionic/react';
import { useEffect, useState } from 'react';

interface Props {
placeholder?: string;
type?: "text" | "email" | "password" | "number";
icon?: string;
text?: string;
isInputSet?: (isSet: boolean) => void;
}

const Input: React.FC<Props> = (props) => {
const [inputText, setInputText] = useState<string | number | undefined>(undefined);

useEffect(() => {
if (inputText) {
props.isInputSet!(true);
} else {
props.isInputSet!(false);
}
}, [inputText])

return (
<div className={styles.inputContainer}>
<div className={styles.inputHolderContainer}>
@@ -21,7 +33,8 @@ const Input: React.FC<Props> = (props) => {
<IonLabel>{props.text}</IonLabel>
}
<IonInput type={props.type ? props.type : "text"}
placeholder={props.placeholder ? props.placeholder : ""}></IonInput>
placeholder={props.placeholder ? props.placeholder : ""}
onIonChange={e => setInputText(e.detail.value!)}></IonInput>
</IonItem>

</div>


+ 0
- 1
src/mockData/QuizDetails.tsx Dosyayı Görüntüle

@@ -6,7 +6,6 @@ interface QuizDetails {
timeLimit: number;
}


let quizDetails: QuizDetails[] = [
{
question: "How would you correctly display, “Hello, how are you?”?",


+ 1
- 1
src/pages/assignment/Assignment.module.scss Dosyayı Görüntüle

@@ -1,7 +1,7 @@
.assignment {

.description {
height: 75vh;
height: 74vh;

.icon {
margin-top: 4rem;


+ 2
- 2
src/pages/assignment/SubmitAssignment.module.scss Dosyayı Görüntüle

@@ -2,7 +2,7 @@
.description {
height: 50vh;
.icon {
margin-top: 4rem;
padding-top: 4rem;
display: flex;
justify-content: center;
ion-icon {
@@ -34,13 +34,13 @@
.inputHolder {
width: 95%;
margin: 0 auto;
height: 25vh;
}
.submitAssigment {
text-decoration: none;
ion-button {
width: 90%;
margin: 0 auto;
margin-top: 12rem;
--background: var(--primary-button-color);
}
}

+ 30
- 9
src/pages/assignment/SubmitAssignment.tsx Dosyayı Görüntüle

@@ -1,15 +1,32 @@
import styles from "./SubmitAssignment.module.scss";
import { IonButton, IonContent, IonIcon, IonPage } from "@ionic/react"
import { IonButton, IonContent, IonIcon, IonPage, useIonToast } from "@ionic/react"
import assignmentImage from "../../assets/icons/Assignment.svg";
import StepHeader from "../../components/stepsHeader/StepHeader";
import Input from "../../components/formInput/Input";
import linkIcon from "../../assets/icons/link.svg";
import time from "../../assets/icons/time.svg";
import { linkOutline } from 'ionicons/icons'
import { linkOutline } from 'ionicons/icons';
import { Link } from "react-router-dom";
import { useState } from "react";

const SubmitAssignment: React.FC = () => {

const [isInput, setIsInput] = useState(false);
const [present, dismiss] = useIonToast();

const isInputSet = (isSet: boolean) => {
setIsInput(isSet);
}


const showToast = () => {
if (!isInput) {
present({
buttons: [{ text: 'close', handler: () => dismiss() }],
message: 'insert project link to submit',
duration: 2000
})
}
}

return (
<IonPage>
<StepHeader roundName="Assignment" stepNumber={4} />
@@ -19,7 +36,6 @@ const SubmitAssignment: React.FC = () => {
<div className={styles.description}>
<div className={styles.icon}>
<IonIcon src={assignmentImage} />

</div>

<div className={styles.stepDescription}>
@@ -31,12 +47,17 @@ const SubmitAssignment: React.FC = () => {
</div>

<div className={styles.inputHolder}>
<Input placeholder="Insert the project Link" icon={linkOutline} />
<Input
placeholder="Insert the project Link"
icon={linkOutline}
isInputSet={isInputSet} />
</div>
<Link to="/ReviewAssignment"
className={styles.submitAssigment}>
<Link to={isInput ? "/ReviewAssignment" : "/SubmitAssignment"}
className={styles.submitAssigment}
onClick={showToast}>
<IonButton shape="round" expand='block'>Submit</IonButton>
</Link>

</IonContent>
</IonPage>
);


+ 4
- 0
src/pages/finalInterview/FinalInterview.tsx Dosyayı Görüntüle

@@ -7,6 +7,8 @@ import locationIcon from "../../assets/icons/location.svg";
import { Link } from "react-router-dom";
import { useState } from "react";
import TimeSlot from "../../components/timeSlot/TimeSlot";
import { useCountdown } from "../../components/CountDownTimer/useCountdown";
import { addDays } from "date-fns";

interface dates {
date: string;
@@ -18,6 +20,8 @@ const FinalInterview: React.FC = () => {
const [isDateSet, setDate] = useState<boolean>(false);
const [isTimeSlot, setTimeSlot] = useState<boolean>(false);

const [days, hours, minutes, seconds] = useCountdown(addDays(new Date(), 3));

const timeSlots = ["11:00 AM - 1:00 pm", "1:00 PM - 3:00 pm", "3:00 PM - 5:00 pm"];

const dates: dates[] = [


+ 2
- 1
src/pages/technicalInterview/TechnicalInterview.tsx Dosyayı Görüntüle

@@ -21,7 +21,8 @@ const TechnicalInterview: React.FC = () => {
const [isDateSet, setDate] = useState<boolean>(false);
const [isTimeSlot, setTimeSlot] = useState<boolean>(false);

const [days, hours, minutes, seconds] = useCountdown(addDays(new Date(), 2));

const [days, hours, minutes, seconds] = useCountdown(addDays(new Date(), 3));

console.log(days, hours, minutes, seconds);



Yükleniyor…
İptal
Kaydet