1
- import Image from "next/image" ;
1
+ "use client"
2
+
3
+ import React , { useEffect , useState } from 'react' ;
4
+ import SingleCard from '@/Components/SingleCard' ;
5
+ import PropagateLoader from "react-spinners/PropagateLoader" ;
6
+
7
+ interface Card {
8
+ src : string ;
9
+ id ?: number ;
10
+ matched : boolean ;
11
+ }
12
+
13
+ const cardImages : Card [ ] = [
14
+ { "src" : "./images/Bulbasaur.png" , matched : false } ,
15
+ { "src" : "./images/Nidoking.png" , matched : false } ,
16
+ { "src" : "./images/Phanpy.png" , matched : false } ,
17
+ { "src" : "./images/Pidgey.png" , matched : false } ,
18
+ { "src" : "./images/Pikachu.png" , matched : false } ,
19
+ { "src" : "./images/Voltorb.png" , matched : false } ,
20
+ ] ;
2
21
3
22
export default function Home ( ) {
4
- return (
5
- < main className = "flex min-h-screen flex-col items-center justify-between p-24" >
6
- < div className = "z-10 max-w-5xl w-full items-center justify-between font-mono text-sm lg:flex" >
7
- < p className = "fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30" >
8
- Get started by editing
9
- < code className = "font-mono font-bold" > app/page.tsx</ code >
10
- </ p >
11
- < div className = "fixed bottom-0 left-0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:h-auto lg:w-auto lg:bg-none" >
12
- < a
13
- className = "pointer-events-none flex place-items-center gap-2 p-8 lg:pointer-events-auto lg:p-0"
14
- href = "https://vercel.com?utm_source=create-next-app& utm_medium = appdir - template & utm_campaign = create - next - app "
15
- target = "_blank"
16
- rel = "noopener noreferrer"
17
- >
18
- By{ " " }
19
- < Image
20
- src = "/vercel.svg"
21
- alt = "Vercel Logo"
22
- className = "dark:invert"
23
- width = { 100 }
24
- height = { 24 }
25
- priority
26
- />
27
- </ a >
28
- </ div >
29
- </ div >
23
+ const [ loading , setLoading ] = useState < boolean > ( false ) ;
24
+ const [ cards , setCards ] = useState < Card [ ] > ( [ ] ) ;
25
+ const [ turns , setTurns ] = useState < number > ( 0 ) ;
26
+ const [ choiceOne , setChoiceOne ] = useState < Card | null > ( null ) ;
27
+ const [ choiceTwo , setChoiceTwo ] = useState < Card | null > ( null ) ;
28
+ const [ disabled , setDisabled ] = useState < boolean > ( false ) ;
29
+ const [ gameStarted , setGameStarted ] = useState < boolean > ( false ) ;
30
+
31
+ const override : React . CSSProperties = {
32
+ display : "flex" ,
33
+ alignItems : "center" ,
34
+ justifyContent : "center" ,
35
+ height : "100vh" ,
36
+ textAlign : "center" ,
37
+ } ;
30
38
31
- < div className = "relative flex place-items-center before:absolute before:h-[300px] before:w-full sm:before:w-[480px] before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] after:absolute after:-z-20 after:h-[180px] after:w-full sm:after:w-[240px] after:translate-x-1/3 after:bg-gradient-conic after:from-sky-200 after:via-blue-200 after:blur-2xl after:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700 before:dark:opacity-10 after:dark:from-sky-900 after:dark:via-[#0141ff] after:dark:opacity-40 before:lg:h-[360px] z-[-1]" >
32
- < Image
33
- className = "relative dark:drop-shadow-[0_0_0.3rem_#ffffff70] dark:invert"
34
- src = "/next.svg"
35
- alt = "Next.js Logo"
36
- width = { 180 }
37
- height = { 37 }
38
- priority
39
- />
40
- </ div >
39
+ const shuffleCards = ( ) => {
40
+ const shuffledCards = [ ...cardImages , ...cardImages ]
41
+ . sort ( ( ) => Math . random ( ) - 0.5 )
42
+ . map ( ( card , index ) => ( { ...card , id : index } ) ) ;
41
43
42
- < div className = "mb-32 grid text-center lg:max-w-5xl lg:w-full lg:mb-0 lg:grid-cols-4 lg:text-left" >
43
- < a
44
- href = "https://nextjs.org/docs?utm_source=create-next-app& utm_medium = appdir - template & utm_campaign = create - next - app "
45
- className = "group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
46
- target = "_blank"
47
- rel = "noopener noreferrer"
48
- >
49
- < h2 className = { `mb-3 text-2xl font-semibold` } >
50
- Docs{ " " }
51
- < span className = "inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none" >
52
- ->
53
- </ span >
54
- </ h2 >
55
- < p className = { `m-0 max-w-[30ch] text-sm opacity-50` } >
56
- Find in-depth information about Next.js features and API.
57
- </ p >
58
- </ a >
44
+ setChoiceOne ( null ) ;
45
+ setChoiceTwo ( null ) ;
46
+ setCards ( shuffledCards ) ;
47
+ setTurns ( 0 ) ;
48
+ setGameStarted ( true ) ;
49
+ } ;
59
50
60
- < a
61
- href = "https://nextjs.org/learn?utm_source=create-next-app& utm_medium = appdir - template - tw & utm_campaign = create - next - app "
62
- className = "group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
63
- target = "_blank"
64
- rel = "noopener noreferrer"
65
- >
66
- < h2 className = { `mb-3 text-2xl font-semibold` } >
67
- Learn{ " " }
68
- < span className = "inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none" >
69
- ->
70
- </ span >
71
- </ h2 >
72
- < p className = { `m-0 max-w-[30ch] text-sm opacity-50` } >
73
- Learn about Next.js in an interactive course with quizzes!
74
- </ p >
75
- </ a >
51
+ const handleChoice = ( card : Card ) => {
52
+ if ( choiceOne && choiceOne . id === card . id ) {
53
+ return ;
54
+ }
76
55
77
- < a
78
- href = "https://vercel.com/templates?framework=next.js& utm_source = create - next - app & utm_medium = appdir - template & utm_campaign = create - next - app "
79
- className = "group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
80
- target = "_blank"
81
- rel = "noopener noreferrer"
82
- >
83
- < h2 className = { `mb-3 text-2xl font-semibold` } >
84
- Templates{ " " }
85
- < span className = "inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none" >
86
- ->
87
- </ span >
88
- </ h2 >
89
- < p className = { `m-0 max-w-[30ch] text-sm opacity-50` } >
90
- Explore starter templates for Next.js.
91
- </ p >
92
- </ a >
56
+ choiceOne ? setChoiceTwo ( card ) : setChoiceOne ( card ) ;
57
+ } ;
93
58
94
- < a
95
- href = "https://vercel.com/new?utm_source=create-next-app& utm_medium = appdir - template & utm_campaign = create - next - app "
96
- className = "group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
97
- target = "_blank"
98
- rel = "noopener noreferrer"
99
- >
100
- < h2 className = { `mb-3 text-2xl font-semibold` } >
101
- Deploy{ " " }
102
- < span className = "inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none" >
103
- ->
104
- </ span >
105
- </ h2 >
106
- < p className = { `m-0 max-w-[30ch] text-sm opacity-50 text-balance` } >
107
- Instantly deploy your Next.js site to a shareable URL with Vercel.
108
- </ p >
109
- </ a >
110
- </ div >
59
+ useEffect ( ( ) => {
60
+ if ( choiceOne && choiceTwo ) {
61
+ setDisabled ( true ) ;
62
+ if ( choiceOne . src === choiceTwo . src ) {
63
+ setCards ( prevCards => {
64
+ return prevCards . map ( card => {
65
+ if ( card . src === choiceOne . src ) {
66
+ return { ...card , matched : true } ;
67
+ } else {
68
+ return card ;
69
+ }
70
+ } ) ;
71
+ } ) ;
72
+ resetTurn ( ) ;
73
+ } else {
74
+ setTimeout ( ( ) => resetTurn ( ) , 1000 ) ;
75
+ }
76
+ }
77
+ } , [ choiceOne , choiceTwo ] ) ;
78
+
79
+ const resetTurn = ( ) => {
80
+ setChoiceOne ( null ) ;
81
+ setChoiceTwo ( null ) ;
82
+ setTurns ( prevTurns => prevTurns + 1 ) ;
83
+ setDisabled ( false ) ;
84
+ } ;
85
+
86
+ useEffect ( ( ) => {
87
+ setLoading ( true ) ;
88
+ setTimeout ( ( ) => {
89
+ shuffleCards ( ) ;
90
+ setLoading ( false ) ;
91
+ } , 1500 ) ;
92
+ } , [ ] ) ;
93
+
94
+ useEffect ( ( ) => {
95
+ if ( gameStarted && cards . every ( card => card . matched === true ) ) {
96
+ setTimeout ( ( ) => {
97
+ shuffleCards ( ) ;
98
+ alert ( `Good job u did ${ turns } turns, wanna try again to break your record` ) ;
99
+ } , 1000 ) ;
100
+ }
101
+ } , [ cards , gameStarted , turns ] ) ;
102
+
103
+ return (
104
+ < main className = "main" >
105
+ {
106
+ loading ?
107
+ < PropagateLoader
108
+ loading = { loading }
109
+ size = { 30 }
110
+ cssOverride = { override }
111
+ />
112
+ :
113
+ < section className = 'container' >
114
+ < article >
115
+ < button className = 'title' > M</ button >
116
+ < button className = 'title' > E</ button >
117
+ < button className = 'title' > M</ button >
118
+ < button className = 'title' > O</ button >
119
+ < button className = 'title' > R</ button >
120
+ < button className = 'title' > Y </ button >
121
+ < button className = 'title' > G</ button >
122
+ < button className = 'title' > A</ button >
123
+ < button className = 'title' > M</ button >
124
+ < button className = 'title' > E</ button >
125
+ </ article >
126
+ < article className = "card-grid" >
127
+ { cards . map ( card => (
128
+ < SingleCard
129
+ key = { card . id }
130
+ card = { card }
131
+ handleChoice = { handleChoice }
132
+ flipped = { card === choiceOne || card === choiceTwo || card . matched }
133
+ disabled = { disabled }
134
+ />
135
+ ) ) }
136
+ </ article >
137
+ </ section >
138
+ }
111
139
</ main >
112
140
) ;
113
- }
141
+ }
0 commit comments