Commit ba6db028 by Arjun Jhukal

made support dynamic with the help of setting and also updated setting at admin functionality

parent d863fa6b
import GlassWrapper from "@/components/molecules/GlassWrapper";
import Link from "next/link";
import { getSupportEmail } from "@/serverApi/game";
import React from "react";
export default function Support() {
export default async function Support() {
let supportEmails = {
customer_support_email: "",
technical_support_email: "",
error: null,
};
try {
const response = await getSupportEmail();
if (response?.data) {
supportEmails = {
customer_support_email: response?.data?.customer_support_email,
technical_support_email: response?.data?.technical_support_email,
error: null,
};
} else {
// supportEmails.error = "No data found. Please try again later.";
return;
}
} catch (error) {
console.error("Error fetching support emails:", error);
// supportEmails.error = "Failed to fetch support email. Please try again later.";
}
if (supportEmails.error) {
return (
<section className="support__root">
<div className="section__title mb-8">
<h1 className="text-[26px] lg:text-[32px] mb-2">Need any Assistance?</h1>
<p className="text-[11px] lg:text-[14px]">{supportEmails.error}</p>
</div>
</section>
);
}
return (
<section className="support__root ">
<section className="support__root">
<div className="section__title mb-8">
<h1 className="text-[26px] lg:text-[32px] mb-2">
Need any Assistance?
</h1>
<h1 className="text-[26px] lg:text-[32px] mb-2">Need any Assistance?</h1>
<p className="text-[11px] lg:text-[14px]">
Here goes the subtitle or description on the assistance need.
</p>
</div>
<div className="grid xl:grid-cols-3 lg:grid-cols-2 grid-cols-1 gap-6">
{/* <GlassWrapper className="p-6">
<img
src="/assets/images/chat.svg"
alt="chat"
className="w-[32px] h-[32px] mb-8"
/>
<h2 className="mb-2 text-[20px]">Live Chat (Fastest)</h2>
<p className="mb-8 text-[11px]">
Here goes the subtitle or description on the assistance need.
</p>
<a
href="#"
className="inline-block text-center px-[22px] py-[11px] rounded-[28px]"
style={{
background: "linear-gradient(90deg, #B100B8 0%, #F335ED 100%)",
}}>
Start Live Chat
</a>
</GlassWrapper> */}
<GlassWrapper className="p-6">
<img
src="/assets/images/support.svg"
......@@ -44,7 +58,9 @@ export default function Support() {
<p className="text-[11px] mb-8">
Questions about your account or gameplay? Our team is here for you.
</p>
<a href="mailto:support@sweepstakeonline.com" className="underline">support@sweepstakeonline.com</a>
<a href={`mailto:${supportEmails.customer_support_email}`} className="underline">
{supportEmails.customer_support_email}
</a>
</GlassWrapper>
<GlassWrapper className="p-6">
<img
......@@ -56,7 +72,9 @@ export default function Support() {
<p className="text-[11px] mb-8">
Questions about your account or gameplay? Our team is here for you.
</p>
<a href="mailto:technical@sweepstakeonline.com" className="underline">technical@sweepstakeonline.com</a>
<a href={`mailto:${supportEmails.technical_support_email}`} className="underline">
{supportEmails.technical_support_email}
</a>
</GlassWrapper>
</div>
</section>
......
......@@ -21,10 +21,10 @@ export async function generateMetadata(): Promise<Metadata> {
return {
title: seoData?.data?.site_name || metadata.title,
description: seoData?.data?.description || metadata.description,
description: seoData?.data?.site_description || metadata.description,
openGraph: {
title: seoData?.data?.site_name || seoData?.data?.site_name || metadata.title,
description: seoData?.data?.description || seoData?.data?.description || metadata.description,
description: seoData?.data?.site_description || seoData?.data?.site_description || metadata.description,
images: seoData?.data?.logo ? [seoData.logo] : ["/assets/images/logo.png"],
},
icons: seoData?.favicon || metadata.icons,
......
......@@ -33,6 +33,9 @@ export default function SiteSetting() {
site_name: data?.data?.site_name,
favicon: null,
logo: null,
site_description: data?.data?.site_description,
customer_support_email: data?.data?.customer_support_email,
technical_support_email: data?.data?.technical_support_email,
unique_selling_points: data?.data?.unique_selling_points.map((usp) => ({
title: usp.title,
description: usp.description,
......@@ -42,7 +45,7 @@ export default function SiteSetting() {
} : SiteInitialRequest,
enableReinitialize: true,
validationSchema: Yup.object({
favicon: Yup.mixed().required("Favicon is required"),
// favicon: Yup.mixed().required("Favicon is required"),
// logo: Yup.mixed().required("Logo is required"),
site_name: Yup.string().required("Website title is required"),
unique_selling_points: Yup.array().of(
......@@ -59,6 +62,9 @@ export default function SiteSetting() {
if (values.favicon) formData.append("favicon", values.favicon);
if (values.logo) formData.append("logo", values.logo);
if (values.site_description) formData.append("site_description", values.site_description);
if (values.technical_support_email) formData.append("technical_support_email", values.technical_support_email);
if (values.customer_support_email) formData.append("customer_support_email", values.customer_support_email);
if (data?.data?.logo) {
formData.append("logo_url", serverFiles.logo)
......@@ -150,6 +156,24 @@ export default function SiteSetting() {
: ""}
</span>
</div>
{/* Website Description */}
<div className="input__field col-span-1 md:col-span-2">
<InputLabel>Website Description<span className="text-red-500">*</span></InputLabel>
<OutlinedInput
fullWidth
name="site_description"
placeholder="Enter Website Description"
value={formik.values.site_description}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
/>
<span className="error">
{formik.touched.site_description && formik.errors.site_description
? formik.errors.site_description
: ""}
</span>
</div>
{/* Favicon */}
<div className="input__field col-span-1 md:col-span-2">
......@@ -182,6 +206,43 @@ export default function SiteSetting() {
{formik.touched.logo && formik.errors.logo ? formik.errors.logo : ""}
</span>
</div>
{/* Customer Support Emaiol */}
<div className="input__field col-span-1 md:col-span-2">
<InputLabel>Customer Support<span className="text-red-500">*</span></InputLabel>
<OutlinedInput
fullWidth
name="customer_support_email"
placeholder="Enter Client Support Email"
value={formik.values.customer_support_email}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
/>
<span className="error">
{formik.touched.customer_support_email && formik.errors.customer_support_email
? formik.errors.customer_support_email
: ""}
</span>
</div>
{/* Customer Support Emaiol */}
<div className="input__field col-span-1 md:col-span-2">
<InputLabel>Technical Support<span className="text-red-500">*</span></InputLabel>
<OutlinedInput
fullWidth
name="technical_support_email"
placeholder="Enter Technical Support Email"
value={formik.values.technical_support_email}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
/>
<span className="error">
{formik.touched.technical_support_email && formik.errors.technical_support_email
? formik.errors.technical_support_email
: ""}
</span>
</div>
</div>
</div>
......
"use client";
import React from 'react'
import SingleGameCred from '../../../gameCredentials/SingleGameCred'
import { useAppSelector } from '@/hooks/hook';
import { useRouter } from 'next/navigation';
export default function GameCredentialsBlock({ game }: { game: any }) {
const user = useAppSelector((s) => s ? s.auth.user : "");
if (!user) {
return "";
}
return (
<div className="game_cred ">
<h2 className="text-[20px]">Credentials for {game?.data?.name}</h2>
<SingleGameCred username={game?.data?.user?.name || ""} password={game?.data?.user?.password || ""} />
</div>
)
}
......@@ -4,6 +4,8 @@ import React, { useState } from "react";
import { Dialog, DialogContent, DialogTitle, IconButton } from "@mui/material";
import { CloseCircle } from "@wandersonalwes/iconsax-react";
import TapIcon from "@/icons/Tap";
import { useAppSelector } from "@/hooks/hook";
import { useRouter } from "next/navigation";
interface GameIframeDialogProps {
gameName: string;
......@@ -21,8 +23,18 @@ export default function GameIframeDialog({
isCredCard
}: GameIframeDialogProps) {
const [open, setOpen] = useState(false);
const user = useAppSelector((s) => s ? s.auth.user : "");
const router = useRouter();
const handleOpen = () => setOpen(true);
const handleOpen = () => {
if (user) {
setOpen(true)
}
else {
router.push("/login");
}
};
const handleClose = () => setOpen(false);
return (
......
"use client"
import { useAppSelector } from '@/hooks/hook'
import GoldCoinIcon from '@/icons/GoldCoinIcon'
import SilverCoinIcon from '@/icons/SilverCoinIcon'
import { useGetUserBalanceBySlugQuery } from '@/services/userApi'
......@@ -8,7 +9,10 @@ import React from 'react'
export default function UserCoin({ slug }: { slug: string }) {
const { data } = useGetUserBalanceBySlugQuery({ slug });
const user = useAppSelector((s) => s ? s.auth.user : "");
if (!user) {
return "";
}
return (
<Box sx={{
background: "linear-gradient(0deg, rgba(234, 47, 231, 0.10) 0%, rgba(234, 47, 231, 0.10) 100%)",
......
......@@ -12,6 +12,8 @@ import UserCoin from "./UserCoin";
import { redirect } from "next/dist/server/api-utils";
import GameIframeDialog from "./GameIframeDialog";
import SingleGameCred from "../../../gameCredentials/SingleGameCred";
import ProtectedLink from "@/routes/ProtectedLink";
import GameCredentialsBlock from "./GameCredentialsBlock";
export default function ExclusiveGameDetail({ game }: { game: SingleGameResponse }) {
......@@ -23,9 +25,10 @@ export default function ExclusiveGameDetail({ game }: { game: SingleGameResponse
<div className="md:grid md:grid-cols-12 flex flex-col gap-8 lg:gap-20">
<div className="col-span-12 md:col-span-4">
<div className="aspect-[420/433] relative rounded-xl overflow-hidden">
<Image src={game?.data?.thumbnail || "/assets/images/fallback.png"} fill className="object-cover" alt={game?.data?.name} />
<div className="aspect-[420/433] relative rounded-xl overflow-hidden mb-4">
<Image src={game?.data?.thumbnail || "/assets/images/fallback.png"} fill className="object-cover " alt={game?.data?.name} />
</div>
<GameCredentialsBlock game={game} />
</div>
<div className="col-span-12 md:col-span-8">
<div className="content__wrapper flex flex-col gap-4">
......@@ -63,10 +66,7 @@ export default function ExclusiveGameDetail({ game }: { game: SingleGameResponse
</div>
<div className="game_cred md:max-w-1/2">
<h2 className="text-[24px]">Credentials for {game?.data?.name}</h2>
<SingleGameCred username={game?.data?.user?.name || ""} password={game?.data?.user?.password || ""} />
</div>
{
game?.data?.is_iframe
......@@ -81,9 +81,9 @@ export default function ExclusiveGameDetail({ game }: { game: SingleGameResponse
)
: game?.data?.game_url
? (
<Link className="ss-btn bg-primary-grad" href={game.data.game_url} target={game?.data?.has_redirection ? "_blank" : "_self"} rel={game?.data?.has_redirection ? "noopener noreferrer" : ""}>
<ProtectedLink className="ss-btn bg-primary-grad" href={game.data.game_url} target={game?.data?.has_redirection ? "_blank" : "_self"} rel={game?.data?.has_redirection ? "noopener noreferrer" : ""}>
Play Now
</Link>
</ProtectedLink>
)
: null
}
......
......@@ -25,7 +25,7 @@ export default async function ExclusiveGamePage() {
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 xl:grid-cols-5 gap-4">
{
games?.data?.data.map((game) => (
<ProtectedLink href={`exclusive-games/${game.id}`} className="group block overflow-hidden hover:shadow-md transition rounded-2xl aspect-[208/222] relative" key={game.id}>
<Link href={`exclusive-games/${game.id}`} className="group block overflow-hidden hover:shadow-md transition rounded-2xl aspect-[208/222] relative" key={game.id}>
<Tooltip title={game.name}>
<Image
src={game.thumbnail || "/assets/images/fallback.png"}
......@@ -34,7 +34,7 @@ export default async function ExclusiveGamePage() {
className="w-full h-[222px] object-cover group-hover:scale-110 transition-transform duration-300"
/>
</Tooltip>
</ProtectedLink>
</Link>
))
}
</div>
......
......@@ -8,9 +8,11 @@ interface Props {
href: string;
className?: string;
children: React.ReactNode;
target?: string;
rel?: string;
}
export default function ProtectedLink({ href, className, children }: Props) {
export default function ProtectedLink({ href, className, children, target, rel }: Props) {
const user = useAppSelector((s) => s ? s.auth.user : "");
const dispatch = useAppDispatch();
const router = useRouter();
......@@ -26,7 +28,7 @@ export default function ProtectedLink({ href, className, children }: Props) {
};
return (
<a href={href} onClick={handleClick} className={className}>
<a href={href} onClick={handleClick} className={className} target={target} rel={rel}>
{children}
</a>
);
......
......@@ -11,6 +11,9 @@ export async function getSubGames(): Promise<any> {
export async function pageSEO(): Promise<any> {
return serverBaseQuery("/api/general/home/seo");
}
export async function getSupportEmail(): Promise<any> {
return serverBaseQuery("/api/general/supports");
}
export async function getUsp(): Promise<any> {
return serverBaseQuery("/api/general/home/usp");
}
......
......@@ -5,12 +5,18 @@ export interface SiteSettingRequestProps {
logo_url?: string;
site_name: string;
unique_selling_points: UspProps[];
site_description: string;
customer_support_email: string;
technical_support_email: string;
}
export const SiteInitialRequest = {
favicon: null,
logo: null,
site_name: "",
customer_support_email: "",
technical_support_email: "",
site_description: "",
unique_selling_points: [
{
title: "",
......@@ -27,6 +33,9 @@ export interface SiteSettingResponseProps {
favicon: string;
logo: string;
site_name: string;
site_description: string;
customer_support_email: string;
technical_support_email: string;
unique_selling_points: {
title: string;
description: string;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment