Last active
February 8, 2024 18:45
-
-
Save Vetrivel-VP/78c072a26208da779f6f11d2f3c6835e to your computer and use it in GitHub Desktop.
Full-Stack App Store
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
-------------------------------------Chat Container------------------------------------------ | |
import React, { useState } from "react"; | |
import { Avatar1, Avatar2, Avatar3, ChatHero, Three } from "../assets"; | |
import { FaUsers } from "react-icons/fa6"; | |
import { BsFillSendFill, BsThreeDots } from "react-icons/bs"; | |
import moment from "moment"; | |
const ChatContainer = () => { | |
const [messages, setMessages] = useState([ | |
{ | |
image: Avatar1, | |
message: "Hi I want to withdraw everything..!This is awesome", | |
time: `${Date.now()}`, | |
isSender: true, | |
}, | |
{ | |
image: Avatar2, | |
message: "Hey guys...How you all doing...It's been so long", | |
time: `${Date.now()}`, | |
isSender: false, | |
}, | |
{ | |
image: Avatar1, | |
message: "We are fine....What about you", | |
time: `${Date.now()}`, | |
isSender: true, | |
}, | |
{ | |
image: Avatar3, | |
message: "Awesome Buddy....", | |
time: `${Date.now()}`, | |
isSender: false, | |
}, | |
]); | |
const [value, setValue] = useState(""); | |
const sendMessage = () => { | |
setMessages([ | |
...messages, | |
{ image: Avatar1, message: value, time: `${Date.now()}` }, | |
]); | |
setValue(""); | |
}; | |
return ( | |
<div className="w-full bg-[#222222] shadow-lg flex-1 h-[calc(100vh-120px)] rounded-[50px] overflow-hidden flex flex-col"> | |
{/* top */} | |
<div className="w-full px-4 bg-[#2B2B2B] flex items-center justify-between"> | |
<div className="flex items-start justify-start flex-col gap-2 px-3"> | |
{/* title */} | |
<div className="flex items-center justify-center gap-1"> | |
<FaUsers className="text-secondary text-lg" /> | |
<p className="text-base text-secondary font-medium">General Chat</p> | |
</div> | |
{/*online counts */} | |
<div className="flex items-center justify-center gap-2"> | |
<div className="flex items-center justify-center"> | |
<img | |
src={Avatar1} | |
className="w-8 h-8 rounded-full object-cover" | |
alt="" | |
/> | |
<img | |
src={Avatar2} | |
className="w-8 h-8 rounded-full object-cover -ml-2" | |
alt="" | |
/> | |
<img | |
src={Avatar3} | |
className="w-8 h-8 rounded-full object-cover -ml-2" | |
alt="" | |
/> | |
</div> | |
<p className="text-sm text-white"> | |
Online : <span className="text-secondary font-medium">172</span> | |
</p> | |
</div> | |
</div> | |
<img src={ChatHero} className="w-28 h-auto object-contain" alt="" /> | |
</div> | |
{/* messages */} | |
<div className="flex-grow overflow-y-scroll w-full px-4 py-2"> | |
{messages && | |
messages.map((msg, index) => ( | |
<> | |
{msg.isSender ? ( | |
<Sender msg={msg} key={index} /> | |
) : ( | |
<Reciever msg={msg} key={index} /> | |
)} | |
</> | |
))} | |
</div> | |
{/* bottom */} | |
<div className="w-full gap-2 h-24 bg-[#2B2B2B] px-6 py-4 flex items-center justify-center"> | |
<input | |
type="text" | |
value={value} | |
onChange={(e) => setValue(e.target.value)} | |
placeholder="Send a message ..." | |
className="flex-1 outline-none border-none bg-transparent text-[#9d9d9d] placeholder:text-[#5d5d5d]" | |
/> | |
<div className="w-[1px] h-6 bg-third"></div> | |
<BsFillSendFill | |
onClick={sendMessage} | |
className="text-secondary text-lg cursor-pointer" | |
/> | |
</div> | |
</div> | |
); | |
}; | |
export const Reciever = ({ msg }) => { | |
return ( | |
<div className="w-full bg-[#1B1B1B] px-2 py-3 rounded-2xl mb-4 shadow-lg shadow-[rgba(0,0,0,0.4)]"> | |
<div className=" flex items-start justify-between gap-2"> | |
<img | |
src={msg?.image} | |
className="w-12 h-12 rounded-full object-cover" | |
alt="" | |
/> | |
<p className="text-sm text-zinc-300 flex-1 text-left">{msg?.message}</p> | |
<BsThreeDots className="text-2xl text-zinc-300" /> | |
</div> | |
<div className="flex items-center justify-end px-4"> | |
<p className="text-sm text-zinc-500"> | |
{moment(new Date(parseInt(msg?.time)).toISOString()).fromNow()} | |
</p> | |
</div> | |
</div> | |
); | |
}; | |
export const Sender = ({ msg }) => { | |
return ( | |
<div className="w-full bg-gradient-to-b from-[#353535] to-[#353535] px-2 py-3 rounded-2xl mb-4 shadow-lg shadow-[rgba(0,0,0,0.4)]"> | |
<div className=" flex items-start justify-between gap-2"> | |
<img | |
src={msg?.image} | |
className="w-12 h-12 rounded-full object-cover" | |
alt="" | |
/> | |
<p className="text-sm text-zinc-300 flex-1 text-left">{msg?.message}</p> | |
<BsThreeDots className="text-2xl text-zinc-300" /> | |
</div> | |
<div className="flex items-center justify-end px-4"> | |
<p className="text-sm text-zinc-500"> | |
{moment(new Date(parseInt(msg?.time)).toISOString()).fromNow()} | |
</p> | |
</div> | |
</div> | |
); | |
}; | |
export default ChatContainer; | |
-------------------------------------------------Helpers----------------------------------------- | |
import { auth } from "../config/firebase.config"; | |
import { | |
FaBehance, | |
FaBolt, | |
FaFacebook, | |
FaLinkedin, | |
FaListCheck, | |
} from "react-icons/fa6"; | |
import { FaUserAlt, FaListAlt } from "react-icons/fa"; | |
import { MdSportsBaseball } from "react-icons/md"; | |
import { | |
GiTrophy, | |
GiTransportationRings, | |
GiCardAceClubs, | |
} from "react-icons/gi"; | |
import { TbTopologyStarRing3 } from "react-icons/tb"; | |
import { BiLogoDiscordAlt, BiSolidJoystick } from "react-icons/bi"; | |
import { RiCustomerService2Fill } from "react-icons/ri"; | |
export const baseURL = | |
"http://127.0.0.1:5001/full-stack-app-store-dec-2023/us-central1"; | |
export const Menus = [ | |
{ id: 10001, menu: "My Profile", uri: "/profile" }, | |
{ id: 10002, menu: "My Favourites", uri: "/favourites" }, | |
{ id: 10003, menu: "Dashboard", uri: "/admin/home", isAdmin: true }, | |
{ id: 10004, menu: "Users", uri: "/admin/users", isAdmin: true }, | |
{ id: 10005, menu: `App's`, uri: "/admin/apps", isAdmin: true }, | |
]; | |
export const signOutTheUser = async (queryClient) => { | |
await auth.signOut().then(() => { | |
queryClient.setQueryData("user", null); | |
}); | |
}; | |
export const ClientMenus = [ | |
{ | |
title: "Sports", | |
submenu: true, | |
Icon: MdSportsBaseball, | |
subMenuItems: [ | |
{ title: "Free Match", Icon: GiTransportationRings }, | |
{ title: "Live Sports", Icon: GiTrophy }, | |
], | |
}, | |
{ | |
title: "Casino", | |
Icon: GiCardAceClubs, | |
spacing: true, | |
}, | |
{ | |
title: "Slot Games", | |
Icon: TbTopologyStarRing3, | |
}, | |
{ | |
title: "Virtual Games", | |
Icon: BiSolidJoystick, | |
}, | |
{ | |
title: "Mini Games", | |
Icon: FaBolt, | |
}, | |
{ | |
title: "Betting History", | |
Icon: FaListAlt, | |
}, | |
{ | |
title: "Community", | |
Icon: FaUserAlt, | |
spacing: true, | |
submenu: true, | |
subMenuItems: [ | |
{ title: "Discord", Icon: BiLogoDiscordAlt }, | |
{ title: "Linked In", Icon: FaLinkedin }, | |
{ title: "Facebook", Icon: FaFacebook }, | |
{ title: "Behnace", Icon: FaBehance }, | |
], | |
}, | |
{ | |
title: "Events List", | |
Icon: FaListCheck, | |
}, | |
{ | |
title: "Customer Services", | |
Icon: RiCustomerService2Fill, | |
}, | |
]; | |
---------------------------------------------Banner.jsx--------------------------------------- | |
import React from "react"; | |
import { One, Two, Three, Four } from "../assets"; | |
import { BiSolidCopyAlt } from "react-icons/bi"; | |
import { | |
MdConfirmationNumber, | |
MdLogout, | |
MdPoll, | |
MdSportsBasketball, | |
MdSportsFootball, | |
} from "react-icons/md"; | |
import { FaAward } from "react-icons/fa6"; | |
import { Swiper, SwiperSlide } from "swiper/react"; | |
import { Autoplay } from "swiper/modules"; | |
import "swiper/css"; | |
import "swiper/css/pagination"; | |
import "swiper/css/navigation"; | |
const Banner = () => { | |
return ( | |
<div className="w-full rounded-[40px] h-64 xl:h-96 bg-fourth overflow-hidden relative shadow-lg shadow-[rgba(0,0,0,0.6)]"> | |
{/* slider */} | |
<Swiper | |
spaceBetween={30} | |
centeredSlides={false} | |
autoplay={{ | |
delay: 2500, | |
disableOnInteraction: false, | |
}} | |
modules={[Autoplay]} | |
className="mySwiper" | |
> | |
<SwiperSlide> | |
<Slide image={One} /> | |
</SwiperSlide> | |
<SwiperSlide> | |
<Slide image={Two} /> | |
</SwiperSlide> | |
<SwiperSlide> | |
<Slide image={Three} /> | |
</SwiperSlide> | |
<SwiperSlide> | |
<Slide image={Four} /> | |
</SwiperSlide> | |
</Swiper> | |
<div className="absolute inset-0 flex items-end justify-end z-50"> | |
<div className="w-full h-auto px-8 py-4 backdrop-blur-md bg-gradient-to-b from-transparent to-[rgba(0,0,0,0.9)] relative flex items-center justify-start gap-6 flex-wrap"> | |
{/* */} | |
<div className="flex items-center justify-center gap-2 group"> | |
<div className="w-6 rounded-md h-6 bg-textSecondary group-hover:bg-secondary flex items-center justify-center"> | |
<MdConfirmationNumber className="text-heroPrimary " /> | |
</div> | |
<p className="text-textSecondary text-sm group-hover:text-secondary"> | |
Luck Numbers | |
</p> | |
</div> | |
{/* */} | |
<div className="flex items-center justify-center gap-2 group"> | |
<div className="w-6 rounded-md h-6 bg-secondary group-hover:bg-secondary flex items-center justify-center"> | |
<MdSportsFootball className="text-heroPrimary " /> | |
</div> | |
<p className="text-secondary text-sm group-hover:text-secondary"> | |
Soccer | |
</p> | |
</div> | |
{/* */} | |
<div className="flex items-center justify-center gap-2 group"> | |
<div className="w-6 rounded-md h-6 bg-textSecondary group-hover:bg-secondary flex items-center justify-center"> | |
<FaAward className="text-heroPrimary " /> | |
</div> | |
<p className="text-textSecondary text-sm group-hover:text-secondary"> | |
Jacpot | |
</p> | |
</div> | |
{/* */} | |
<div className="flex items-center justify-center gap-2 group"> | |
<div className="w-6 rounded-md h-6 bg-textSecondary group-hover:bg-secondary flex items-center justify-center"> | |
<MdPoll className="text-heroPrimary " /> | |
</div> | |
<p className="text-textSecondary text-sm group-hover:text-secondary"> | |
Bet Games | |
</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
); | |
}; | |
export const Slide = ({ image }) => { | |
return ( | |
<div className="w-full h-full"> | |
<img src={image} className="w-full h-full object-cover" alt="" /> | |
<div className="absolute inset-0 bg-gradient-to-r from-[rgba(0,0,0,0.6)] to-transparent"> | |
<div className="w-full h-full flex flex-col items-start justify-start px-4 py-2 lg:px-8 lg:py-6 "> | |
<h1 | |
className="text-xl lg:text-3xl font-bold text-white tracking-wide" | |
style={{ textShadow: "5px 5px 8px rgba(0,0,0,0.6)" }} | |
> | |
We give money for the{" "} | |
<span className="block">first registration!</span> | |
</h1> | |
<p className="mt-2 text-white"> | |
<span className="text-secondary">Free $100!</span> Register and | |
enter a special code | |
</p> | |
<div className="mt-3 flex items-center justify-center gap-8"> | |
<div className="px-4 py-2 rounded-full border-2 border-dashed border-secondary bg-bgGlobal flex items-center justify-center gap-2"> | |
<BiSolidCopyAlt className="text-secondary" /> | |
<p className="text-sm font-bold text-white">#FREE5</p> | |
</div> | |
<div className="bg-gradient-to-r from-heroPrimary to-heroSecondory rounded-full px-4 py-2 shadow-lg flex items-center justify-center gap-2"> | |
<MdLogout className=" text-black" /> | |
<p className="text-sm font-medium text-black">SignUp</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
); | |
}; | |
export default Banner; | |
-----------------------------------------Details.jsx------------------------------------------ | |
import React, { useEffect, useState } from "react"; | |
import useApps from "../hooks/apps/useApps"; | |
import { MainLoader } from "../components"; | |
import { useNavigate, useParams } from "react-router-dom"; | |
import { | |
MdArrowBack, | |
MdArrowForward, | |
MdBookmarkAdd, | |
MdShare, | |
MdStar, | |
} from "react-icons/md"; | |
import { FaComputer } from "react-icons/fa6"; | |
import { Swiper, SwiperSlide } from "swiper/react"; | |
import "swiper/css"; | |
const Detail = () => { | |
const { appid } = useParams(); | |
const [loadedApp, setLoadedApp] = useState(null); | |
const { | |
data: apps, | |
isLoading: appsLoading, | |
isError: appsError, | |
refetch: appsRefetch, | |
} = useApps(); | |
useEffect(() => { | |
if (appid && apps && apps?.length > 0) { | |
setLoadedApp(apps.filter((app) => app?._id === appid)[0]); | |
} | |
}, [apps]); | |
if (appsLoading) { | |
return <MainLoader />; | |
} | |
return ( | |
<div className="overflow-y-scroll scrollbar-none h-full"> | |
<AppBanner loadedApp={loadedApp} /> | |
<div className="w-full h-full grid grid-cols-1 lg:grid-cols-12 gap-4 px-8 py-4 "> | |
{/* left section */} | |
<div className="col-span-12 lg:col-span-8 flex flex-col items-center justify-start gap-3"> | |
{/* Slider */} | |
<div className="w-full overflow-x-scroll scrollbar-none py-6"> | |
<Swiper | |
slidesPerView={2} | |
spaceBetween={20} | |
grabCursor={true} | |
className="mySwiper" | |
> | |
{loadedApp?.banners && | |
loadedApp?.banners?.map((img, index) => ( | |
<SwiperSlide style={{ width: 500 }} key={index}> | |
<div className="duration-200 w-auto h-64 rounded overflow-hidden relative"> | |
<img | |
src={img?.uri} | |
className="w-auto h-full object-cover" | |
alt="" | |
/> | |
</div> | |
</SwiperSlide> | |
))} | |
</Swiper> | |
</div> | |
{/* about this game */} | |
<div className="w-full flex flex-col items-start justify-start gap-3 py-6"> | |
<div className="flex items-center justify-center gap-12"> | |
<p className="text-2xl text-gray-300">About this game</p> | |
<MdArrowForward className="text-2xl text-gray-300" /> | |
</div> | |
<p className="text-base text-gray-400"> | |
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Nam, | |
porro! Quibusdam maiores beatae aspernatur dolor iste voluptas sed | |
aperiam quaerat illo facere. Praesentium omnis amet quam numquam, | |
placeat nisi animi. | |
</p> | |
<p className="text-base text-gray-400"> | |
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Nam, | |
porro! Quibusdam maiores beatae aspernatur dolor iste voluptas sed | |
aperiam quaerat illo facere. Praesentium omnis amet quam numquam, | |
placeat nisi animi. | |
</p> | |
</div> | |
</div> | |
{/* Simillar card section */} | |
<div className="col-span-4 h-full px-2 py-4 hidden lg:flex flex-col items-start justify-start gap-4"> | |
<div className="flex items-center justify-center gap-12"> | |
<p className="text-2xl text-gray-300">Simillar Apps</p> | |
<MdArrowForward className="text-2xl text-gray-300" /> | |
</div> | |
{apps && | |
apps | |
.filter((game) => game._id !== appid) | |
.map((value, index) => ( | |
<div | |
className="w-full px-3 py-2 flex items-start justify-start gap-2" | |
key={index} | |
> | |
<img | |
src={value?.appIcon} | |
className="w-12 h-12 rounded-md object-cover" | |
alt="" | |
/> | |
<div className="flex flex-col items-start justify-start gap-2"> | |
<p className="text-base font-medium text-gray-400"> | |
{value?.title} | |
</p> | |
<div className="flex items-center justify-start gap-1"> | |
<p className="text-sm font-medium text-gray-600"> | |
{value?.reviews} | |
</p> | |
<MdStar className="text-gray-600" /> | |
</div> | |
</div> | |
</div> | |
))} | |
</div> | |
</div> | |
</div> | |
); | |
}; | |
export const AppBanner = ({ loadedApp }) => { | |
const navigate = useNavigate(); | |
return ( | |
<div className="w-full h-[550px] bg-[#282828] relative"> | |
<img | |
src={loadedApp?.cover} | |
className="w-full h-full object-cover" | |
alt="" | |
/> | |
{/* absolute overlay */} | |
<div className="absolute inset-0 bg-gradient-to-tr from-black via-[rgba(0,0,0,0.8)] to-transparent flex flex-col items-start justify-between z-10"> | |
<div | |
className="px-8 pt-8 hover:translate-x-3 duration-200 cursor-pointer" | |
onClick={() => navigate(-1)} | |
> | |
<MdArrowBack className="text-3xl text-gray-200" /> | |
</div> | |
<div className="w-full px-8 py-12 flex items-start justify-start flex-col gap-5"> | |
{/* Title */} | |
<h2 className="text-gray-200 text-3xl lg:text-5xl font-medium"> | |
{loadedApp?.title} | |
</h2> | |
{/* company details */} | |
<div className="flex flex-col items-start justify-start"> | |
<p className="text-secondary font-medium">{loadedApp?.company}</p> | |
<p className="text-xs text-gray-400 flex items-center justify-center gap-2"> | |
Contains ads | |
<span> | |
<div className="w-[1px] h-[1px] rounded-full bg-gray-400"></div> | |
</span> | |
In-app purchases | |
</p> | |
</div> | |
{/* logo , ratings sections */} | |
<div className=" flex items-center justify-center gap-8"> | |
<img | |
src={loadedApp?.appIcon} | |
className="w-12 h-12 rounded-lg object-cover" | |
alt="" | |
/> | |
{/* ratings */} | |
<div className="flex flex-col items-center justify-center gap-1"> | |
<p className="text-base font-medium text-gray-200 flex items-center justify-center"> | |
{loadedApp?.reviews} | |
<MdStar className="text-gray-200 text-xs" /> | |
</p> | |
<span className="text-[12px] text-gray-400"> | |
{loadedApp?.totalReviews} reviews | |
</span> | |
</div> | |
{/* downloads */} | |
<div className="flex flex-col items-center justify-center gap-1"> | |
<p className="text-base font-medium text-gray-200"> | |
{loadedApp?.downloads} | |
</p> | |
<span className="text-[12px] text-gray-400">Downloads</span> | |
</div> | |
{/* rated */} | |
<div className="flex flex-col items-center justify-center gap-2"> | |
<p className="text-sm font-medium text-black flex items-center justify-center bg-gray-200"> | |
{loadedApp?.rated} | |
</p> | |
<span className="text-[12px] text-gray-400"> | |
Rated for {loadedApp?.rated} | |
</span> | |
</div> | |
</div> | |
{/* download */} | |
<div className="flex items-center justify-center gap-8"> | |
<button className="border-none outline-none bg-gradient-to-r from-heroPrimary bg-heroSecondory rounded-md px-12 py-2 font-medium"> | |
Install | |
</button> | |
<MdShare className="text-secondary text-2xl cursor-pointer" /> | |
<MdBookmarkAdd className="text-secondary text-2xl cursor-pointer" /> | |
</div> | |
<div className="flex items-center justify-center flex-wrap gap-8"> | |
<div className="flex items-center justify-center gap-2"> | |
<FaComputer className="text-gray-400 text-sm" /> | |
<p className="text-gray-400 text-xs"> | |
This app is not available for your device | |
</p> | |
</div> | |
<div className="flex items-center justify-center gap-2"> | |
<img | |
src="https://lh3.googleusercontent.com/1d_Ubja0DGaHuhzY8zJga9oG7gS0xwPomKryvehUMEnT667MbNI_SIV2uf6C_BYcX17dlpioO28Qr-dq9ngIbUVcOpNxBrF_D9_yJ7mfDRFG5zbN7Q=s1000" | |
alt="" | |
className="w-4 h-auto object-contain" | |
/> | |
<p className="text-gray-400 text-xs"> | |
Get items in this app or game with Play Points. Learn more | |
</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
); | |
}; | |
export default Detail; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment