10 | TypeArena is a cutting-edge platform designed to help individuals improve their typing skills through engaging challenges and competitions. Our mission is to make typing practice fun, social, and rewarding.
11 |
12 |
13 | Founded in Oct 2024, TypeArena has quickly grown to become a favorite among typing enthusiasts, students, and professionals looking to enhance their keyboard proficiency. Our team of dedicated developers and typing experts work tirelessly to create new challenges, improve user experience, and foster a supportive community.
14 |
15 |
16 | At TypeArena, we believe that strong typing skills are essential in today's digital world. Whether you're a beginner looking to increase your typing speed or an expert aiming to break records, TypeArena offers a range of features to help you achieve your goals.
17 |
10 | Welcome to TypeArena. By using our website and services, you agree to comply with and be bound by the following terms and conditions of use. Please review these terms carefully.
11 |
12 |
1. Acceptance of Terms
13 |
14 | By accessing or using TypeArena, you agree to these Terms of Service and our Privacy Policy. If you do not agree to these terms, you must not use our service.
15 |
16 |
2. Changes to Terms
17 |
18 | We reserve the right to modify or replace these terms at any time. Your continued use of TypeArena after any such changes constitutes your acceptance of the new terms.
19 |
20 |
3. User Accounts
21 |
22 | You are responsible for safeguarding the password that you use to access TypeArena and for any activities or actions under your password. We encourage you to use "strong" passwords (passwords that use a combination of upper and lower case letters, numbers, and symbols) with your account.
23 |
24 |
4. Content and Conduct
25 |
26 | You are solely responsible for your conduct and any data, text, information, usernames, graphics, images, photos, profiles, audio, video, or other content ("Content") that you submit, post, or display on TypeArena.
27 |
28 |
5. Termination
29 |
30 | We may terminate or suspend your account and bar access to the service immediately, without prior notice or liability, under our sole discretion, for any reason whatsoever and without limitation, including but not limited to a breach of the Terms.
31 |
15 |
16 |
17 | How do I start a typing test?
18 |
19 | To start a typing test, simply click on the "Play Now" button in the navigation menu. You'll be taken to our playground where you can choose from various typing challenges and tests.
20 |
21 |
22 |
23 | Is TypeArena free to use?
24 |
25 | Yes, TypeArena is completely free to use. We offer a range of features and challenges at no cost. However, we may introduce premium features in the future for users who want an enhanced experience.
26 |
27 |
28 |
29 | How are the typing speeds calculated?
30 |
31 | Typing speeds are calculated in words per minute (WPM). We use the standard definition of a word as 5 characters, including spaces. Your net WPM is calculated by subtracting your errors from your gross WPM.
32 |
33 |
34 |
35 | Can I compete with my friends?
36 |
37 | You can create private rooms and invite your friends to compete in real-time typing races. You can also compare your scores on our global and friend leaderboards.
38 |
39 |
40 |
41 | How can I improve my typing speed?
42 |
43 | Regular practice is key to improving your typing speed. Use our daily challenges, personalized practice sessions, and themed tests to work on your weaknesses. Also, focus on accuracy first, and speed will naturally follow with consistent practice.
44 |
45 |
46 |
47 |
48 |
49 |
10 | At TypeArena, we take your privacy seriously. This Privacy Policy explains how we collect, use, disclose, and safeguard your information when you use our website and services.
11 |
12 |
1. Information We Collect
13 |
14 | We collect information that you provide directly to us, such as when you create an account, participate in typing tests, or contact us for support. This may include your name, email address, and typing statistics.
15 |
16 |
2. How We Use Your Information
17 |
18 | We use the information we collect to provide, maintain, and improve our services, to communicate with you, and to monitor and analyze trends and usage of TypeArena.
19 |
20 |
3. Information Sharing and Disclosure
21 |
22 | We do not share, sell, or transfer your personal information to third parties except as described in this policy. We may share aggregated or de-identified information that cannot reasonably be used to identify you.
23 |
24 |
4. Data Security
25 |
26 | We use reasonable measures to help protect information about you from loss, theft, misuse, unauthorized access, disclosure, alteration, and destruction. However, no internet or email transmission is ever fully secure or error-free.
27 |
28 |
5. Your Choices
29 |
30 | You may update, correct, or delete your account information at any time by logging into your online account. You may also contact us to request access to, correction of, or deletion of any personal information that you have provided to us.
31 |
32 |
6. Changes to this Policy
33 |
34 | We may change this privacy policy from time to time. If we make changes, we will notify you by revising the date at the top of the policy and, in some cases, we may provide you with additional notice.
35 |
148 |
149 | );
150 | }
151 |
--------------------------------------------------------------------------------
/src/data/sampleParagraphs.ts:
--------------------------------------------------------------------------------
1 | const sampleParagraphs = {
2 | "paragraphs": [
3 | {
4 | "id": 1,
5 | "text": "the beach is a calm place to rest waves are soft the sand is warm and the wind is cool people love to swim build in sand or just sit and enjoy the view the sunsets are bright and colorful and sometimes you may even see dolphins swimming in the sea"
6 | },
7 | {
8 | "id": 2,
9 | "text": "a forest is quiet and full of life birds sing and the trees move with the wind sunlight comes through the trees making the ground glow you can walk on soft paths and hear the sounds of nature you might even see small animals like rabbits or deer hiding nearby"
10 | },
11 | {
12 | "id": 3,
13 | "text": "mountains are big and full of beauty people hike or climb them to enjoy fresh air and amazing views in spring flowers bloom and cover the hills in winter they are covered in snow making them perfect for skiing the top of a mountain shows how wide and vast the world is"
14 | },
15 | {
16 | "id": 4,
17 | "text": "cities are full of people and fun things to do there are tall homes parks and busy streets shops are everywhere and you can always find new foods to try at night the lights make the city bright and alive some parks offer quiet spots to rest from the busy day"
18 | },
19 | {
20 | "id": 5,
21 | "text": "the ocean is huge and has so many fish and plants people love to swim sail or even dive under the water to see life dolphins turtles and colorful fish live there we need to keep the water clean and safe so the ocean can stay full of life for years to come"
22 | },
23 | {
24 | "id": 6,
25 | "text": "phones and computers help us stay close to others even far away they make work and school easy to manage but they can also be hard to handle when used too much it is good to take breaks go outside and talk to people face to face when possible"
26 | },
27 | {
28 | "id": 7,
29 | "text": "saving the earth means using less and helping more we can plant trees save water and use less power solar energy from the sun and windmills can make clean power if we all work together we can make the earth a better home for animals plants and people"
30 | },
31 | {
32 | "id": 8,
33 | "text": "ai helps people work faster and smarter it can read big data and give quick answers doctors use it to find health problems and stores use it to help people shop but ai must be fair and people need to guide it to make sure it does good things"
34 | },
35 | {
36 | "id": 9,
37 | "text": "the brain helps us think and feel in smart ways it works with the body to move learn and grow people study the brain to help solve sadness and stress with new ideas we can find better ways to stay happy and healthy while making smarter choices in life"
38 | },
39 | {
40 | "id": 10,
41 | "text": "the weather is changing fast and this is not good for animals or people ice is melting and some animals are losing their homes we need to use clean power save trees and drive less to help small actions like these can make a big change over time"
42 | },
43 | {
44 | "id": 11,
45 | "text": "gardens are full of colors with flowers fruits and trees birds and bees visit to help plants grow people enjoy sitting in gardens to relax or read planting a garden at home can be fun and gives fresh fruits and veggies to eat it also helps keep the air clean"
46 | },
47 | {
48 | "id": 12,
49 | "text": "rivers flow with fresh water for plants animals and people people swim fish and sail on rivers they bring life to the land around them keeping rivers clean is important for the health of all living things trash and waste must be kept far from these precious waters"
50 | },
51 | {
52 | "id": 13,
53 | "text": "rainbows are a magical sight after rain they appear when sunlight hits water drops in the air kids and adults love looking for all the colors in a rainbow they remind us how beautiful nature is seeing one can make any rainy day feel bright and cheerful again"
54 | },
55 | {
56 | "id": 14,
57 | "text": "books open up a world of stories and knowledge they let us travel to new places and meet new people in our minds reading helps us learn new words and ideas you can read about animals space or fun adventures books are like doors to exciting new worlds"
58 | },
59 | {
60 | "id": 15,
61 | "text": "sports are fun and help keep the body strong people love to play soccer run or swim playing in teams teaches sharing and working together sports also make us happy and give us energy everyone can find a sport they enjoy and it is a great way to make friends"
62 | },
63 | {
64 | "id": 16,
65 | "text": "clouds in the sky are soft and white floating high above us sometimes they are gray and bring rain watching clouds is calming and they can look like animals or shapes when the sun sets clouds turn orange and pink making the sky look like a big painting"
66 | },
67 | {
68 | "id": 17,
69 | "text": "the desert is dry and sandy but it is full of life cacti store water and animals like lizards live there deserts are very hot in the day and cool at night people visit to see the wide open land and the clear stars shining bright in the dark sky"
70 | },
71 | {
72 | "id": 18,
73 | "text": "farms are where food is grown farmers work hard to plant and care for crops there are animals like cows hens and sheep that give us milk eggs and wool visiting a farm teaches how food reaches our tables and shows how much care is needed for it"
74 | },
75 | {
76 | "id": 19,
77 | "text": "the zoo is a fun place to see animals from around the world lions elephants and penguins live there zoos teach us about animals and how to care for them they also help save animals that are in danger kids and adults love to visit and learn at zoos"
78 | },
79 | {
80 | "id": 20,
81 | "text": "the sky at night is full of stars and wonders people use telescopes to see planets and moons the moon glows bright and shooting stars make wishes fun stargazing is peaceful and helps us feel small but part of a big beautiful universe filled with mysteries to explore"
82 | }
83 | ]
84 | };
85 |
86 | export default sampleParagraphs;
87 |
--------------------------------------------------------------------------------
/src/components/ui/select.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import {
5 | CaretSortIcon,
6 | CheckIcon,
7 | ChevronDownIcon,
8 | ChevronUpIcon,
9 | } from "@radix-ui/react-icons"
10 | import * as SelectPrimitive from "@radix-ui/react-select"
11 |
12 | import { cn } from "@/lib/utils"
13 |
14 | const Select = SelectPrimitive.Root
15 |
16 | const SelectGroup = SelectPrimitive.Group
17 |
18 | const SelectValue = SelectPrimitive.Value
19 |
20 | const SelectTrigger = React.forwardRef<
21 | React.ElementRef,
22 | React.ComponentPropsWithoutRef
23 | >(({ className, children, ...props }, ref) => (
24 | span]:line-clamp-1",
28 | className
29 | )}
30 | {...props}
31 | >
32 | {children}
33 |
34 |
35 |
36 |
37 | ))
38 | SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
39 |
40 | const SelectScrollUpButton = React.forwardRef<
41 | React.ElementRef,
42 | React.ComponentPropsWithoutRef
43 | >(({ className, ...props }, ref) => (
44 |
52 |
53 |
54 | ))
55 | SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
56 |
57 | const SelectScrollDownButton = React.forwardRef<
58 | React.ElementRef,
59 | React.ComponentPropsWithoutRef
60 | >(({ className, ...props }, ref) => (
61 |
69 |
70 |
71 | ))
72 | SelectScrollDownButton.displayName =
73 | SelectPrimitive.ScrollDownButton.displayName
74 |
75 | const SelectContent = React.forwardRef<
76 | React.ElementRef,
77 | React.ComponentPropsWithoutRef
78 | >(({ className, children, position = "popper", ...props }, ref) => (
79 |
80 |
91 |
92 |
99 | {children}
100 |
101 |
102 |
103 |
104 | ))
105 | SelectContent.displayName = SelectPrimitive.Content.displayName
106 |
107 | const SelectLabel = React.forwardRef<
108 | React.ElementRef,
109 | React.ComponentPropsWithoutRef
110 | >(({ className, ...props }, ref) => (
111 |
116 | ))
117 | SelectLabel.displayName = SelectPrimitive.Label.displayName
118 |
119 | const SelectItem = React.forwardRef<
120 | React.ElementRef,
121 | React.ComponentPropsWithoutRef
122 | >(({ className, children, ...props }, ref) => (
123 |
131 |
132 |
133 |
134 |
135 |
136 | {children}
137 |
138 | ))
139 | SelectItem.displayName = SelectPrimitive.Item.displayName
140 |
141 | const SelectSeparator = React.forwardRef<
142 | React.ElementRef,
143 | React.ComponentPropsWithoutRef
144 | >(({ className, ...props }, ref) => (
145 |
150 | ))
151 | SelectSeparator.displayName = SelectPrimitive.Separator.displayName
152 |
153 | export {
154 | Select,
155 | SelectGroup,
156 | SelectValue,
157 | SelectTrigger,
158 | SelectContent,
159 | SelectLabel,
160 | SelectItem,
161 | SelectSeparator,
162 | SelectScrollUpButton,
163 | SelectScrollDownButton,
164 | }
165 |
--------------------------------------------------------------------------------
/src/app/(pages)/subscription/page.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 | import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from "@/components/ui/card"
3 | import { Button } from "@/components/ui/button"
4 | import { useState } from "react"
5 | import axios from "axios"
6 | import useAuthStore from "@/store/useStore"
7 | import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
8 | import { AlertCircle , Loader2} from "lucide-react"
9 |
10 | //TODO: check for login before payment ✅
11 | // add spinner while creating order in the background so it doesnt call multiple times ✅
12 | // add subscription model and u are subsriped also update the profile to PRO
13 | //
14 |
15 |
16 | export default function SubscriptionPage() {
17 | const [productId,setProductId ] = useState("subscription")
18 | const [varient,setVarient ] = useState("lifetime")
19 | const {isAuthenticated} = useAuthStore()
20 | const [isHovered, setIsHovered] = useState(false)
21 | const [isLoading, setIsLoading] = useState(false)
22 |
23 |
24 | const handleCheckOut = async () => {
25 | setIsLoading(true)
26 | const res = await axios.post("/api/orders",{
27 | productId,
28 | varient
29 | })
30 | setIsLoading(false)
31 |
32 | const { razorpayOrder, order } = res.data;
33 |
34 | // Step 2: Razorpay payment options
35 | const options = {
36 | key: process.env.NEXT_PUBLIC_RAZORPAY_KEY_ID || "",
37 | amount: razorpayOrder.amount,
38 | currency: razorpayOrder.currency,
39 | name: "TypeArena",
40 | description: "Lifetime Subscription",
41 | order_id: razorpayOrder.id,
42 | handler: async (response: any) => {
43 | try {
44 | const verificationRes = await axios.post("/api/verify-payment", {
45 | razorpay_order_id: response.razorpay_order_id,
46 | razorpay_payment_id: response.razorpay_payment_id,
47 | razorpay_signature: response.razorpay_signature,
48 | });
49 |
50 | if (verificationRes.data.success) {
51 | alert("Payment Successful! Subscription Activated.");
52 | // Update UI or redirect user
53 | window.location.reload();
54 | } else {
55 | alert("Payment Verification Failed. Please contact support.");
56 | }
57 | } catch (error) {
58 | console.error("Verification Error:", error);
59 | alert("An error occurred during payment verification. Please contact support.");
60 | }
61 | },
62 | // can be retrive from the user data
63 | prefill: {
64 | name: "Aman Jain",
65 | email: "jainaman0744@gmail.com",
66 | contact: "9826747763",
67 | },
68 | theme: {
69 | color: "#3399cc",
70 | },
71 | };
72 |
73 | // Step 3: Open Razorpay checkout
74 | const razorpay = new (window as any).Razorpay(options);
75 | razorpay.open();
76 |
77 | }
78 |
79 |
80 | return (
81 |