Başlıklar ve Seed
This commit is contained in:
parent
ce886ee5e1
commit
880329d3ae
37 changed files with 842 additions and 535 deletions
|
|
@ -505,6 +505,12 @@
|
|||
"en": "Abp Settings",
|
||||
"tr": "Abp Ayarları"
|
||||
},
|
||||
{
|
||||
"resourceName": "Platform",
|
||||
"key": "App.ChangeLog",
|
||||
"en": "Change Log",
|
||||
"tr": "Versiyon Günlüğü"
|
||||
},
|
||||
{
|
||||
"resourceName": "Platform",
|
||||
"key": "App.BlogManagement",
|
||||
|
|
@ -6343,6 +6349,24 @@
|
|||
"tr": "Ürünler",
|
||||
"en": "Products"
|
||||
},
|
||||
{
|
||||
"resourceName": "Platform",
|
||||
"key": "Public.nav.checkout",
|
||||
"tr": "Organizasyon Seçimi",
|
||||
"en": "Select Organization"
|
||||
},
|
||||
{
|
||||
"resourceName": "Platform",
|
||||
"key": "Public.nav.payment",
|
||||
"tr": "Ödeme",
|
||||
"en": "Payment"
|
||||
},
|
||||
{
|
||||
"resourceName": "Platform",
|
||||
"key": "Public.nav.success",
|
||||
"tr": "Sipariş Durumu",
|
||||
"en": "Success"
|
||||
},
|
||||
{
|
||||
"resourceName": "Platform",
|
||||
"key": "Public.nav.basket",
|
||||
|
|
|
|||
|
|
@ -82,11 +82,12 @@ define(['./workbox-54d0af47'], (function (workbox) { 'use strict';
|
|||
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
||||
}, {
|
||||
"url": "index.html",
|
||||
"revision": "0.172lu27b4eg"
|
||||
"revision": "0.6nc9e67jtoo"
|
||||
}], {});
|
||||
workbox.cleanupOutdatedCaches();
|
||||
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
||||
allowlist: [/^\/$/]
|
||||
allowlist: [/^\/$/],
|
||||
denylist: [/^\/api\//]
|
||||
}));
|
||||
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="description" content="Kurs Platform" />
|
||||
<title>Kurs Platform</title>
|
||||
<meta name="description" content="Sözsoft" />
|
||||
<title>Sözsoft</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ const Simple = ({ children, content, ...rest }: SimpleProps) => {
|
|||
return (
|
||||
<div className="h-full">
|
||||
<Container className="flex flex-col flex-auto items-center justify-center min-w-0 h-full">
|
||||
<Card className="min-w-[320px] md:min-w-[450px]" bodyClass="md:p-10">
|
||||
<Card className="min-w-[320px] md:min-w-[450px]" bodyClass="md:p-6">
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
{!hasSubdomain() && (
|
||||
<a
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { useStoreState } from '@/store'
|
|||
const HeaderLogo = () => {
|
||||
const mode = useStoreState((state) => state.theme.mode)
|
||||
|
||||
return <Logo mode={mode} className="hidden md:block" />
|
||||
return <Logo mode={mode} className="hidden md:block" imgClass="w-9/12" />
|
||||
}
|
||||
|
||||
export default HeaderLogo
|
||||
|
|
|
|||
|
|
@ -73,7 +73,10 @@ export const useMenuData = () => {
|
|||
|
||||
try {
|
||||
// Flatten the hierarchy for API
|
||||
const flatten = (items: MenuItem[], parentCode: string | null = null): MenuItem[] => {
|
||||
const flatten = (
|
||||
items: MenuItem[],
|
||||
parentCode: string | undefined = undefined,
|
||||
): MenuItem[] => {
|
||||
const result: MenuItem[] = []
|
||||
items.forEach((item, index) => {
|
||||
const flatItem = {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import DoubleSidedImage from '@/components/shared/DoubleSidedImage'
|
|||
import { Button } from '@/components/ui'
|
||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { MdArrowBack } from 'react-icons/md'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
|
|
@ -15,6 +16,11 @@ const AccessDenied = () => {
|
|||
|
||||
return (
|
||||
<Container className="h-full">
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('::' + 'Access Denied')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
<div className="h-full flex flex-col items-center justify-center p-28">
|
||||
<DoubleSidedImage
|
||||
src="/img/others/img-2.png"
|
||||
|
|
@ -29,7 +35,9 @@ const AccessDenied = () => {
|
|||
size="xs"
|
||||
className="mt-2"
|
||||
variant="default"
|
||||
onClick={() => navigate(isAdminPath ? ROUTES_ENUM.protected.dashboard : ROUTES_ENUM.public.home)}
|
||||
onClick={() =>
|
||||
navigate(isAdminPath ? ROUTES_ENUM.protected.dashboard : ROUTES_ENUM.public.home)
|
||||
}
|
||||
>
|
||||
<MdArrowBack />
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -5,13 +5,11 @@ const Dashboard = () => {
|
|||
const { translate } = useLocalization()
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('::' + 'Home')}
|
||||
title={translate('::' + 'Dashboard')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
const NotFoundPage = () => {
|
||||
|
|
@ -11,6 +12,11 @@ const NotFoundPage = () => {
|
|||
|
||||
return (
|
||||
<div className="p-28">
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('::' + 'Not Found')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
<div className="flex items-center justify-center font-inter">
|
||||
<div className="text-[8rem] sm:text-[10rem] md:text-[12rem] font-bold bg-gradient-to-br from-primary to-secondary bg-clip-text animate-pulse">
|
||||
404
|
||||
|
|
@ -21,7 +27,9 @@ const NotFoundPage = () => {
|
|||
</p>
|
||||
<div className="flex items-center justify-center font-inter">
|
||||
<button
|
||||
onClick={() => navigate(isAdminPath ? ROUTES_ENUM.protected.dashboard : ROUTES_ENUM.public.home)}
|
||||
onClick={() =>
|
||||
navigate(isAdminPath ? ROUTES_ENUM.protected.dashboard : ROUTES_ENUM.public.home)
|
||||
}
|
||||
className="px-6 py-3 bg-primary rounded-xl shadow hover:bg-secondary transition"
|
||||
>
|
||||
{translate('::Public.notFound.button')}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import merge from 'lodash/merge'
|
|||
import { useEffect, useState } from 'react'
|
||||
import Log from './components/Log'
|
||||
import LogFilter from './components/LogFilter'
|
||||
import { Helmet } from 'react-helmet'
|
||||
|
||||
const itemsPerPage = 10
|
||||
|
||||
|
|
@ -80,6 +81,12 @@ const ActivityLog = () => {
|
|||
|
||||
return (
|
||||
<Container>
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('::' + 'Abp.Identity.ActivityLogs')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
|
||||
<AdaptableCard>
|
||||
<div className="grid lg:grid-cols-5 gap-8">
|
||||
<div className="col-span-4">
|
||||
|
|
|
|||
|
|
@ -263,6 +263,12 @@ function ChartEdit() {
|
|||
|
||||
return chartValues && roleList && userList && permissionOptions ? (
|
||||
<div>
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={chartCode}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
|
||||
<Formik
|
||||
initialValues={{ ...chartValues }}
|
||||
validationSchema={chartValidationSchema}
|
||||
|
|
@ -284,12 +290,6 @@ function ChartEdit() {
|
|||
{({ touched, errors, resetForm, isSubmitting, values }) => (
|
||||
<Form>
|
||||
<FormContainer size="sm">
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={chartCode}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
|
||||
<div className="lg:flex items-center justify-between mb-4 gap-3">
|
||||
<div className="mb-4 lg:mb-0">
|
||||
<h4>
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ const Wizard = () => {
|
|||
<Container>
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('::' + 'Wizard')}
|
||||
title={translate('::' + 'App.Listforms.Wizard')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import Container from '@/components/shared/Container'
|
|||
import Tabs from '@/components/ui/Tabs'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { Suspense, lazy, useState } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
|
||||
type AccountSetting = {
|
||||
|
|
@ -66,6 +67,11 @@ const Profile = () => {
|
|||
|
||||
return (
|
||||
<Container>
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('::' + 'Abp.Identity.Profile')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
<AdaptableCard>
|
||||
<Tabs value={currentTab} onChange={(val) => onTabChange(val)}>
|
||||
<TabList>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { useLocalization } from '@/utils/hooks/useLocalization'
|
|||
import { getAi } from '@/services/ai.service'
|
||||
import { AiDto } from '@/proxy/ai/models'
|
||||
import { Container } from '@/components/shared'
|
||||
import { Helmet } from 'react-helmet'
|
||||
|
||||
// Types
|
||||
type ChatType = 'chat' | 'query' | 'analyze'
|
||||
|
|
@ -264,6 +265,12 @@ const Assistant = () => {
|
|||
// Render
|
||||
return (
|
||||
<Container>
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('::' + 'Abp.Identity.Ai')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
|
||||
<LoadAiPostsFromLocalStorage />
|
||||
<div className="h-[calc(100vh-140px)] flex flex-col">
|
||||
<div className="flex-1 overflow-y-auto p-4 space-y-4">
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import { useLocalization } from '@/utils/hooks/useLocalization'
|
|||
import useTimeOutMessage from '@/utils/hooks/useTimeOutMessage'
|
||||
import { Field, Form, Formik } from 'formik'
|
||||
import { useState } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import * as Yup from 'yup'
|
||||
|
||||
type ExtendLoginFormSchema = {
|
||||
|
|
@ -53,15 +54,27 @@ const ExtendLogin = () => {
|
|||
|
||||
return emailSent ? (
|
||||
<>
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('AbpAccount::' + 'Abp.Account.ExtendLogin')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
<div>
|
||||
<h3 className="mb-1">{translate('::Abp.Account.ExtendLogin.Title')}</h3>
|
||||
<p>{translate('::Abp.Account.ExtendLogin.Description')}</p>
|
||||
<div className="mt-4 text-center">
|
||||
<span>{translate('::Abp.Account.Backto')} </span>
|
||||
<ActionLink to={signInUrl}>{translate('::Abp.Account.SignIn')}</ActionLink>
|
||||
</div>{' '}
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<div>
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('::' + 'Abp.Account.ExtendLogin')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
<div className="mb-6">
|
||||
<h3 className="mb-1">{translate('::Abp.Account.ExtendLogin')}</h3>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import type { AxiosError } from 'axios'
|
|||
import { Field, Form, Formik } from 'formik'
|
||||
import { motion } from 'framer-motion'
|
||||
import { useState } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import * as Yup from 'yup'
|
||||
|
||||
type ForgotPasswordFormSchema = {
|
||||
|
|
@ -56,6 +57,12 @@ const ForgotPassword = () => {
|
|||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('::' + 'Abp.Account.ForgotPassword')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 100 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
|
|
@ -124,6 +131,7 @@ const ForgotPassword = () => {
|
|||
)}
|
||||
</Formik>
|
||||
</motion.div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import { useEffect, useRef, useState } from 'react'
|
|||
import { useNavigate } from 'react-router-dom'
|
||||
import * as Yup from 'yup'
|
||||
import { getSubdomain } from '@/utils/subdomain'
|
||||
import { Helmet } from 'react-helmet'
|
||||
|
||||
type SignInFormSchema = {
|
||||
userName: string
|
||||
|
|
@ -195,6 +196,12 @@ const Login = () => {
|
|||
: undefined
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('AbpAccount::' + 'Login')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 100 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
|
|
@ -323,6 +330,7 @@ const Login = () => {
|
|||
</Formik>
|
||||
</div>
|
||||
</motion.div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import { Field, Form, Formik } from 'formik'
|
|||
import { useState } from 'react'
|
||||
import * as Yup from 'yup'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { Helmet } from 'react-helmet'
|
||||
|
||||
type SignUpFormSchema = {
|
||||
password: string
|
||||
|
|
@ -60,7 +61,13 @@ const Register = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<div className="mb-8">
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('AbpAccount::' + 'Register')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
|
||||
<div className="mb-4">
|
||||
<h3 className="mb-1">{translate('::Abp.Account.Register.Title')}</h3>
|
||||
<p>{translate('::Abp.Account.Register.Message')}</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import useTimeOutMessage from '@/utils/hooks/useTimeOutMessage'
|
|||
import type { AxiosError } from 'axios'
|
||||
import { Field, Form, Formik } from 'formik'
|
||||
import { useState } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { useNavigate, useSearchParams } from 'react-router-dom'
|
||||
import * as Yup from 'yup'
|
||||
|
||||
|
|
@ -77,6 +78,11 @@ const ResetPassword = () => {
|
|||
|
||||
return (
|
||||
<div>
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('AbpAccount::' + 'ResetPassword')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
<div className="mb-6">
|
||||
{resetComplete ? (
|
||||
<>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { ROUTES_ENUM } from '@/routes/route.constant'
|
|||
import { store } from '@/store'
|
||||
import Captcha from '@/components/shared/Captcha'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { Helmet } from 'react-helmet'
|
||||
|
||||
type FormSchema = {
|
||||
email: string
|
||||
|
|
@ -34,6 +35,12 @@ const SendConfirmationCode = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('::' + 'Abp.Account.SendConfirmationCode')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
|
||||
<div className="mb-8">
|
||||
<h3 className="mb-1">{translate('::Abp.Account.SendConfirmationCode')}</h3>
|
||||
<p>{translate('::Abp.Account.SendConfirmationCode.Message')}</p>
|
||||
|
|
@ -85,7 +92,9 @@ const SendConfirmationCode = () => {
|
|||
</Button>
|
||||
<div className="mt-4 text-center">
|
||||
<span>{translate('::Abp.Account.Backto')} </span>
|
||||
<ActionLink to={ROUTES_ENUM.authenticated.login}>{translate('::Abp.Account.SignIn')}</ActionLink>
|
||||
<ActionLink to={ROUTES_ENUM.authenticated.login}>
|
||||
{translate('::Abp.Account.SignIn')}
|
||||
</ActionLink>
|
||||
</div>
|
||||
</FormContainer>
|
||||
</Form>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { Alert, Button } from '@/components/ui'
|
|||
import { useNavigate, useParams } from 'react-router-dom'
|
||||
import useAccount from '@/utils/hooks/useAccount'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { Helmet } from 'react-helmet'
|
||||
|
||||
const VerifyConfirmationCode = () => {
|
||||
const { userId, token } = useParams()
|
||||
|
|
@ -19,6 +20,12 @@ const VerifyConfirmationCode = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('::' + 'Abp.Account.VerifyConfirmationCode')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
|
||||
<div>
|
||||
{message && (
|
||||
<Alert showIcon className="mb-4" type="success">
|
||||
|
|
|
|||
|
|
@ -2,14 +2,25 @@ import React from 'react'
|
|||
import { EntityProvider } from '@/contexts/EntityContext'
|
||||
import DeveloperLayout from '@/components/layouts/DeveloperLayout'
|
||||
import Dashboard from '@/components/developerKit/Dashboard'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { Helmet } from 'react-helmet'
|
||||
|
||||
const DashboardPage: React.FC = () => {
|
||||
const { translate } = useLocalization()
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('::' + 'App.DeveloperKit')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
<DeveloperLayout>
|
||||
<EntityProvider>
|
||||
<Dashboard />
|
||||
</EntityProvider>
|
||||
</DeveloperLayout>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import AdaptableCard from '@/components/shared/AdaptableCard'
|
||||
import Container from '@/components/shared/Container'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import type { ReactNode } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
|
||||
type Log = {
|
||||
version: string
|
||||
|
|
@ -17,33 +19,22 @@ const logData: Log[] = [
|
|||
{
|
||||
version: '1.0.3',
|
||||
date: '04 Şubat 2025',
|
||||
updateContent: [
|
||||
'[Fix] GridBoxEditorComponent bug',
|
||||
'[Fix] TagBoxEditorComponent bug',
|
||||
],
|
||||
updateContent: ['[Fix] GridBoxEditorComponent bug', '[Fix] TagBoxEditorComponent bug'],
|
||||
},
|
||||
{
|
||||
version: '1.0.2',
|
||||
date: '27 Ocak 2025',
|
||||
updateContent: [
|
||||
'[Add] jspdf kurulumu',
|
||||
'[Add] exceljs kurulumu',
|
||||
'[Add] file-saver kurulumu',
|
||||
],
|
||||
updateContent: ['[Add] jspdf kurulumu', '[Add] exceljs kurulumu', '[Add] file-saver kurulumu'],
|
||||
},
|
||||
{
|
||||
version: '1.0.1',
|
||||
date: '23 Ocak 2025',
|
||||
updateContent: [
|
||||
'[Fix] Bağımlılık güvenlik açığı',
|
||||
],
|
||||
updateContent: ['[Fix] Bağımlılık güvenlik açığı'],
|
||||
},
|
||||
{
|
||||
version: '1.0.0',
|
||||
date: '20 Ocak 2025',
|
||||
updateContent: [
|
||||
'[Update] İlk yeni sürüm',
|
||||
],
|
||||
updateContent: ['[Update] İlk yeni sürüm'],
|
||||
},
|
||||
]
|
||||
|
||||
|
|
@ -51,29 +42,28 @@ const Log = (props: LogProps) => {
|
|||
return (
|
||||
<div className={`py-4 ${props.border && 'border-bottom'}`}>
|
||||
<div className="flex items-center">
|
||||
<h5 className="font-weight-normal mb-0 mr-3">
|
||||
{props.version}
|
||||
</h5>
|
||||
<h5 className="font-weight-normal mb-0 mr-3">{props.version}</h5>
|
||||
<code>{props.date}</code>
|
||||
</div>
|
||||
<div className="api-container p-0 border-0 mt-3">
|
||||
{props.children}
|
||||
</div>
|
||||
<div className="api-container p-0 border-0 mt-3">{props.children}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const Changelog = () => {
|
||||
const { translate } = useLocalization()
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('::' + 'App.ChangeLog')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
<AdaptableCard>
|
||||
<h4>Platform Güncelleme Günlüğü</h4>
|
||||
{logData.map((elm) => (
|
||||
<Log
|
||||
key={elm.version}
|
||||
version={`v${elm.version}`}
|
||||
date={elm.date}
|
||||
>
|
||||
<Log key={elm.version} version={`v${elm.version}`} date={elm.date}>
|
||||
{elm.updateContent.length > 0 ? (
|
||||
<ul>
|
||||
{elm.updateContent.map((item, i) => (
|
||||
|
|
|
|||
|
|
@ -4,8 +4,12 @@ import React, { useState, useEffect } from 'react'
|
|||
import { useForumData } from './useForumData'
|
||||
import { ForumView } from './forum/ForumView'
|
||||
import { Container } from '@/components/shared'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
|
||||
export function Forum() {
|
||||
const { translate } = useLocalization()
|
||||
|
||||
const { user, tenant } = useStoreState((state) => state.auth)
|
||||
const {
|
||||
categories,
|
||||
|
|
@ -47,6 +51,12 @@ export function Forum() {
|
|||
|
||||
return (
|
||||
<Container>
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('::' + 'App.Forum')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
|
||||
{error && (
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4">
|
||||
<div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative">
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ import { useEffect } from 'react'
|
|||
import { useForumData } from './useForumData'
|
||||
import { AdminView } from './admin/AdminView'
|
||||
import { Container } from '@/components/shared'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
|
||||
export function Management() {
|
||||
const {
|
||||
|
|
@ -31,6 +33,7 @@ export function Management() {
|
|||
unmarkPostAsAcceptedAnswer,
|
||||
clearError,
|
||||
} = useForumData()
|
||||
const { translate } = useLocalization()
|
||||
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
|
|
@ -54,6 +57,12 @@ export function Management() {
|
|||
|
||||
return (
|
||||
<Container>
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('::' + 'App.ForumManagement')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
|
||||
{error && (
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4">
|
||||
<div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative">
|
||||
|
|
|
|||
|
|
@ -4,11 +4,15 @@ import { MenuItem } from '@/@types/menu'
|
|||
import { useMenuData } from '@/utils/hooks/useMenuData'
|
||||
import { AlertCircle, Loader2, Menu, Save } from 'lucide-react'
|
||||
import { Container } from '@/components/shared'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
|
||||
export const MenuManager = () => {
|
||||
const { menuItems, setMenuItems, loading, error, refetch, saveMenuData } = useMenuData()
|
||||
const [isDesignMode, setIsDesignMode] = useState(true)
|
||||
const [isSaving, setIsSaving] = useState(false)
|
||||
const { translate } = useLocalization()
|
||||
|
||||
const [saveMessage, setSaveMessage] = useState<{
|
||||
type: 'success' | 'error'
|
||||
text: string
|
||||
|
|
@ -78,6 +82,12 @@ export const MenuManager = () => {
|
|||
|
||||
return (
|
||||
<Container>
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('::' + 'App.Menus.Manager')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
|
||||
<div className="bg-white rounded px-4 sm:px-4 lg:px-6 py-6">
|
||||
<div className="flex items-center justify-between mb-6 flex-wrap gap-4">
|
||||
{/* Sol kısım: Başlık */}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import React from 'react'
|
|||
import { Users, Award, Clock, Globe2 } from 'lucide-react'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { useCountUp } from '@/utils/hooks/useCountUp'
|
||||
import { Helmet } from 'react-helmet'
|
||||
|
||||
const About: React.FC = () => {
|
||||
const { translate } = useLocalization()
|
||||
|
|
@ -12,6 +13,13 @@ const About: React.FC = () => {
|
|||
const countriesCount = useCountUp({ end: 3, duration: 1500 })
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet
|
||||
titleTemplate="%s | Sözsoft"
|
||||
title={translate('::' + 'Public.about.title')}
|
||||
defaultTitle="Sözsoft"
|
||||
></Helmet>
|
||||
|
||||
<div className="min-h-screen bg-gray-50">
|
||||
{/* Hero Section */}
|
||||
<div className="relative bg-blue-900 text-white py-12">
|
||||
|
|
@ -103,6 +111,7 @@ const About: React.FC = () => {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,30 +1,31 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Calendar, Clock, User, Tag, Search } from "lucide-react";
|
||||
import { format } from "date-fns";
|
||||
import { tr } from "date-fns/locale";
|
||||
import { BlogCategory, BlogPost } from "@/proxy/blog/blog";
|
||||
import { blogService } from "@/services/blog.service";
|
||||
import { useLocalization } from "@/utils/hooks/useLocalization";
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { Calendar, Clock, User, Tag, Search } from 'lucide-react'
|
||||
import { format } from 'date-fns'
|
||||
import { tr } from 'date-fns/locale'
|
||||
import { BlogCategory, BlogPost } from '@/proxy/blog/blog'
|
||||
import { blogService } from '@/services/blog.service'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { Helmet } from 'react-helmet'
|
||||
|
||||
const Blog = () => {
|
||||
const { translate } = useLocalization()
|
||||
|
||||
const [posts, setPosts] = useState<BlogPost[]>([]);
|
||||
const [categories, setCategories] = useState<BlogCategory[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [selectedCategory, setSelectedCategory] = useState<string>("");
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [totalPages, setTotalPages] = useState(1);
|
||||
const [posts, setPosts] = useState<BlogPost[]>([])
|
||||
const [categories, setCategories] = useState<BlogCategory[]>([])
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [selectedCategory, setSelectedCategory] = useState<string>('')
|
||||
const [searchQuery, setSearchQuery] = useState('')
|
||||
const [currentPage, setCurrentPage] = useState(1)
|
||||
const [totalPages, setTotalPages] = useState(1)
|
||||
|
||||
useEffect(() => {
|
||||
loadBlogData();
|
||||
}, [currentPage, selectedCategory]);
|
||||
loadBlogData()
|
||||
}, [currentPage, selectedCategory])
|
||||
|
||||
const loadBlogData = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setLoading(true)
|
||||
const [postsData, categoriesData] = await Promise.all([
|
||||
blogService.getPosts({
|
||||
page: currentPage,
|
||||
|
|
@ -33,29 +34,29 @@ const Blog = () => {
|
|||
search: searchQuery,
|
||||
}),
|
||||
blogService.getCategories(),
|
||||
]);
|
||||
])
|
||||
|
||||
setPosts(postsData.items.filter(a=> a.isPublished));
|
||||
setTotalPages(postsData.totalPages);
|
||||
setCategories(categoriesData.filter(a=> a.isActive));
|
||||
setPosts(postsData.items.filter((a) => a.isPublished))
|
||||
setTotalPages(postsData.totalPages)
|
||||
setCategories(categoriesData.filter((a) => a.isActive))
|
||||
} catch (error) {
|
||||
console.error("Blog verileri yüklenemedi:", error);
|
||||
setPosts([]);
|
||||
console.error('Blog verileri yüklenemedi:', error)
|
||||
setPosts([])
|
||||
} finally {
|
||||
setLoading(false);
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleSearch = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
setCurrentPage(1);
|
||||
loadBlogData();
|
||||
};
|
||||
e.preventDefault()
|
||||
setCurrentPage(1)
|
||||
loadBlogData()
|
||||
}
|
||||
|
||||
const handleCategoryChange = (categoryId: string) => {
|
||||
setSelectedCategory(categoryId);
|
||||
setCurrentPage(1);
|
||||
};
|
||||
setSelectedCategory(categoryId)
|
||||
setCurrentPage(1)
|
||||
}
|
||||
|
||||
if (loading && posts.length === 0) {
|
||||
return (
|
||||
|
|
@ -64,11 +65,16 @@ const Blog = () => {
|
|||
<p className="mt-4 text-gray-600">Blog yazıları yükleniyor...</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50">
|
||||
<Helmet
|
||||
titleTemplate="%s | Sözsoft"
|
||||
title={translate('::' + 'Public.blog.title')}
|
||||
defaultTitle="Sözsoft"
|
||||
></Helmet>
|
||||
{/* Hero Section */}
|
||||
<div className="relative bg-blue-900 text-white py-12">
|
||||
<div
|
||||
|
|
@ -76,12 +82,14 @@ const Blog = () => {
|
|||
style={{
|
||||
backgroundImage:
|
||||
'url("https://images.pexels.com/photos/3183164/pexels-photo-3183164.jpeg?auto=compress&cs=tinysrgb&w=1920")',
|
||||
backgroundSize: "cover",
|
||||
backgroundPosition: "center",
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
}}
|
||||
></div>
|
||||
<div className="container mx-auto pt-20 relative">
|
||||
<h1 className="text-5xl font-bold ml-4 mt-3 mb-2 text-white">{translate('::Public.blog.title')}</h1>
|
||||
<h1 className="text-5xl font-bold ml-4 mt-3 mb-2 text-white">
|
||||
{translate('::Public.blog.title')}
|
||||
</h1>
|
||||
<p className="text-xl max-w-3xl ml-4">{translate('::Public.blog.subtitle')}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -107,11 +115,11 @@ const Blog = () => {
|
|||
{/* Category Filter */}
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
<button
|
||||
onClick={() => handleCategoryChange("")}
|
||||
onClick={() => handleCategoryChange('')}
|
||||
className={`px-4 py-2 rounded-lg transition-colors ${
|
||||
selectedCategory === ""
|
||||
? "bg-blue-600 text-white"
|
||||
: "bg-gray-200 text-gray-700 hover:bg-gray-300"
|
||||
selectedCategory === ''
|
||||
? 'bg-blue-600 text-white'
|
||||
: 'bg-gray-200 text-gray-700 hover:bg-gray-300'
|
||||
}`}
|
||||
>
|
||||
Tümü
|
||||
|
|
@ -122,8 +130,8 @@ const Blog = () => {
|
|||
onClick={() => handleCategoryChange(category.id)}
|
||||
className={`px-4 py-2 rounded-lg transition-colors ${
|
||||
selectedCategory === category.id
|
||||
? "bg-blue-600 text-white"
|
||||
: "bg-gray-200 text-gray-700 hover:bg-gray-300"
|
||||
? 'bg-blue-600 text-white'
|
||||
: 'bg-gray-200 text-gray-700 hover:bg-gray-300'
|
||||
}`}
|
||||
>
|
||||
{translate('::Public.' + category.name)} ({category.postCount})
|
||||
|
|
@ -138,24 +146,16 @@ const Blog = () => {
|
|||
<div className="container mx-auto px-4 py-16">
|
||||
{!Array.isArray(posts) || posts.length === 0 ? (
|
||||
<div className="text-center py-12">
|
||||
<p className="text-gray-600 text-lg">
|
||||
Henüz blog yazısı bulunmuyor.
|
||||
</p>
|
||||
<p className="text-gray-600 text-lg">Henüz blog yazısı bulunmuyor.</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
{posts.map((post) => (
|
||||
<Link
|
||||
to={`/blog/${post.slug || post.id}`}
|
||||
key={post.id}
|
||||
className="block"
|
||||
>
|
||||
<Link to={`/blog/${post.slug || post.id}`} key={post.id} className="block">
|
||||
<article className="bg-white rounded-xl shadow-lg overflow-hidden hover:shadow-xl transition-shadow h-full flex flex-col">
|
||||
<div className="aspect-w-16 aspect-h-9 relative">
|
||||
<img
|
||||
src={
|
||||
post.coverImage
|
||||
}
|
||||
src={post.coverImage}
|
||||
alt={post.title}
|
||||
className="object-cover w-full h-48"
|
||||
/>
|
||||
|
|
@ -167,7 +167,9 @@ const Blog = () => {
|
|||
<h2 className="text-xl font-bold text-gray-900 mb-3 hover:text-blue-600 transition-colors">
|
||||
{translate('::Public.' + post.title)}
|
||||
</h2>
|
||||
<p className="text-gray-600 mb-4 flex-1">{translate('::Public.' + post.summary)}</p>
|
||||
<p className="text-gray-600 mb-4 flex-1">
|
||||
{translate('::Public.' + post.summary)}
|
||||
</p>
|
||||
|
||||
{/* Tags */}
|
||||
{post.tags.length > 0 && (
|
||||
|
|
@ -191,11 +193,9 @@ const Blog = () => {
|
|||
</div>
|
||||
<div className="flex items-center">
|
||||
<Calendar size={16} className="mr-1" />
|
||||
{format(
|
||||
new Date(post.publishedAt || post.creationTime),
|
||||
"dd MMM yyyy",
|
||||
{ locale: tr }
|
||||
)}
|
||||
{format(new Date(post.publishedAt || post.creationTime), 'dd MMM yyyy', {
|
||||
locale: tr,
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -223,8 +223,8 @@ const Blog = () => {
|
|||
onClick={() => setCurrentPage(i + 1)}
|
||||
className={`px-4 py-2 rounded-lg ${
|
||||
currentPage === i + 1
|
||||
? "bg-blue-600 text-white"
|
||||
: "border border-gray-300 hover:bg-gray-50"
|
||||
? 'bg-blue-600 text-white'
|
||||
: 'border border-gray-300 hover:bg-gray-50'
|
||||
}`}
|
||||
>
|
||||
{i + 1}
|
||||
|
|
@ -232,9 +232,7 @@ const Blog = () => {
|
|||
))}
|
||||
|
||||
<button
|
||||
onClick={() =>
|
||||
setCurrentPage(Math.min(totalPages, currentPage + 1))
|
||||
}
|
||||
onClick={() => setCurrentPage(Math.min(totalPages, currentPage + 1))}
|
||||
disabled={currentPage === totalPages}
|
||||
className="px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
|
|
@ -267,7 +265,7 @@ const Blog = () => {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default Blog;
|
||||
export default Blog
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { blogService } from '@/services/blog.service'
|
|||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { useStoreState } from '@/store/store'
|
||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||
import { Helmet } from 'react-helmet'
|
||||
|
||||
interface PostData {
|
||||
image?: string
|
||||
|
|
@ -78,9 +79,17 @@ const BlogDetail: React.FC = () => {
|
|||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50">
|
||||
<Helmet
|
||||
titleTemplate="%s | Sözsoft"
|
||||
title={translate('::' + 'Public.blog.title')}
|
||||
defaultTitle="Sözsoft"
|
||||
></Helmet>
|
||||
<div className="relative bg-blue-900 text-white py-12"></div>
|
||||
<div className="container mx-auto px-4">
|
||||
<Link to={ROUTES_ENUM.public.blog} className="text-blue-600 hover:underline mt-4 mb-4 inline-block">
|
||||
<Link
|
||||
to={ROUTES_ENUM.public.blog}
|
||||
className="text-blue-600 hover:underline mt-4 mb-4 inline-block"
|
||||
>
|
||||
← {translate('::Public.blog.backToBlog')}
|
||||
</Link>
|
||||
{postData.image && (
|
||||
|
|
@ -90,7 +99,9 @@ const BlogDetail: React.FC = () => {
|
|||
className="w-full h-96 object-cover rounded-lg mb-8"
|
||||
/>
|
||||
)}
|
||||
<h1 className="text-4xl font-bold text-gray-900 mb-6">{translate('::Public.' + blogPost.title)}</h1>
|
||||
<h1 className="text-4xl font-bold text-gray-900 mb-6">
|
||||
{translate('::Public.' + blogPost.title)}
|
||||
</h1>
|
||||
<div className="flex items-center text-sm text-gray-500 space-x-4 mb-8">
|
||||
<div className="flex items-center">
|
||||
<span>{postData.author?.name}</span>
|
||||
|
|
@ -105,7 +116,10 @@ const BlogDetail: React.FC = () => {
|
|||
<div
|
||||
className="prose max-w-none text-gray-800"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: currentLang == 'tr' ? translate(blogPost.contentTr!!) : translate(blogPost.contentEn!!),
|
||||
__html:
|
||||
currentLang == 'tr'
|
||||
? translate(blogPost.contentTr!!)
|
||||
: translate(blogPost.contentEn!!),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,12 +8,16 @@ import {
|
|||
removeItemFromCart,
|
||||
updateCartItemQuantity,
|
||||
} from '@/utils/cartUtils'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
const Checkout: React.FC = () => {
|
||||
const navigate = useNavigate()
|
||||
const [isCartOpen, setIsCartOpen] = useState(false)
|
||||
const { translate } = useLocalization()
|
||||
|
||||
const [cartState, setCartState] = useState<CartState>(() => {
|
||||
const savedCart = localStorage.getItem('cartState')
|
||||
return savedCart ? JSON.parse(savedCart) : initialCartState
|
||||
|
|
@ -55,6 +59,12 @@ const Checkout: React.FC = () => {
|
|||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50">
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('::' + 'Public.nav.checkout')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
|
||||
{/* Hero Section */}
|
||||
<div className="relative bg-blue-900 text-white py-12">
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React from "react";
|
||||
import React from 'react'
|
||||
import {
|
||||
Mail,
|
||||
Phone,
|
||||
|
|
@ -8,14 +8,21 @@ import {
|
|||
CalendarDays,
|
||||
CalendarCheck,
|
||||
MessageCircle,
|
||||
} from "lucide-react";
|
||||
import { useLocalization } from "@/utils/hooks/useLocalization";
|
||||
} from 'lucide-react'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { Helmet } from 'react-helmet'
|
||||
|
||||
const Contact: React.FC = () => {
|
||||
const { translate } = useLocalization()
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50">
|
||||
<Helmet
|
||||
titleTemplate="%s | Sözsoft"
|
||||
title={translate('::' + 'Public.contact.title')}
|
||||
defaultTitle="Sözsoft"
|
||||
></Helmet>
|
||||
|
||||
{/* Hero Section */}
|
||||
<div className="relative bg-blue-900 text-white py-12">
|
||||
<div
|
||||
|
|
@ -23,12 +30,14 @@ const Contact: React.FC = () => {
|
|||
style={{
|
||||
backgroundImage:
|
||||
'url("https://images.pexels.com/photos/3183171/pexels-photo-3183171.jpeg?auto=compress&cs=tinysrgb&w=1920")',
|
||||
backgroundSize: "cover",
|
||||
backgroundPosition: "center",
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
}}
|
||||
></div>
|
||||
<div className="container mx-auto pt-20 relative">
|
||||
<h1 className="text-5xl font-bold ml-4 mt-3 mb-2 text-white">{translate('::Public.contact.title')}</h1>
|
||||
<h1 className="text-5xl font-bold ml-4 mt-3 mb-2 text-white">
|
||||
{translate('::Public.contact.title')}
|
||||
</h1>
|
||||
<p className="text-xl max-w-3xl ml-4">{translate('::Public.contact.subtitle')}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -46,9 +55,7 @@ const Contact: React.FC = () => {
|
|||
<div className="flex items-start space-x-4">
|
||||
<MapPin className="w-6 h-6 text-blue-600 flex-shrink-0 mt-1" />
|
||||
<div>
|
||||
<p className="text-gray-600">
|
||||
{translate('::Public.contact.address.full')}
|
||||
</p>
|
||||
<p className="text-gray-600">{translate('::Public.contact.address.full')}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start space-x-4">
|
||||
|
|
@ -96,9 +103,7 @@ const Contact: React.FC = () => {
|
|||
className="w-24 object-contain mt-1 flex-shrink-0"
|
||||
/>
|
||||
<div>
|
||||
<h3 className="font-semibold text-gray-900">
|
||||
Özlem Öztürk
|
||||
</h3>
|
||||
<h3 className="font-semibold text-gray-900">Özlem Öztürk</h3>
|
||||
<p className="text-gray-600">
|
||||
03663 / Enpara
|
||||
<br />
|
||||
|
|
@ -163,7 +168,7 @@ const Contact: React.FC = () => {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default Contact;
|
||||
export default Contact
|
||||
|
|
|
|||
|
|
@ -17,46 +17,123 @@ import {
|
|||
} from 'lucide-react'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||
import { Helmet } from 'react-helmet'
|
||||
|
||||
const Home: React.FC = () => {
|
||||
const { translate } = useLocalization()
|
||||
|
||||
const features = [
|
||||
{ icon: <Users className="w-12 h-12 text-blue-500" />, title: translate('::Public.features.reliable'), description: translate('::Public.features.reliable.desc') },
|
||||
{ icon: <Calendar className="w-12 h-12 text-blue-500" />, title: translate('::Public.features.rapid'), description: translate('::Public.features.rapid.desc') },
|
||||
{ icon: <BookOpen className="w-12 h-12 text-blue-500" />, title: translate('::Public.features.expert'), description: translate('::Public.features.expert.desc') },
|
||||
{ icon: <CreditCard className="w-12 h-12 text-blue-500" />, title: translate('::Public.features.muhasebe'), description: translate('::Public.features.muhasebe.desc') },
|
||||
{ icon: <MessageSquare className="w-12 h-12 text-blue-500" />, title: translate('::Public.features.iletisim'), description: translate('::Public.features.iletisim.desc') },
|
||||
{ icon: <Phone className="w-12 h-12 text-blue-500" />, title: translate('::Public.features.mobil'), description: translate('::Public.features.mobil.desc') },
|
||||
{ icon: <BarChart className="w-12 h-12 text-blue-500" />, title: translate('::Public.features.scalable'), description: translate('::Public.features.scalable.desc') },
|
||||
{ icon: <Shield className="w-12 h-12 text-blue-500" />, title: translate('::Public.features.guvenlik'), description: translate('::Public.features.guvenlik.desc') },
|
||||
{
|
||||
icon: <Users className="w-12 h-12 text-blue-500" />,
|
||||
title: translate('::Public.features.reliable'),
|
||||
description: translate('::Public.features.reliable.desc'),
|
||||
},
|
||||
{
|
||||
icon: <Calendar className="w-12 h-12 text-blue-500" />,
|
||||
title: translate('::Public.features.rapid'),
|
||||
description: translate('::Public.features.rapid.desc'),
|
||||
},
|
||||
{
|
||||
icon: <BookOpen className="w-12 h-12 text-blue-500" />,
|
||||
title: translate('::Public.features.expert'),
|
||||
description: translate('::Public.features.expert.desc'),
|
||||
},
|
||||
{
|
||||
icon: <CreditCard className="w-12 h-12 text-blue-500" />,
|
||||
title: translate('::Public.features.muhasebe'),
|
||||
description: translate('::Public.features.muhasebe.desc'),
|
||||
},
|
||||
{
|
||||
icon: <MessageSquare className="w-12 h-12 text-blue-500" />,
|
||||
title: translate('::Public.features.iletisim'),
|
||||
description: translate('::Public.features.iletisim.desc'),
|
||||
},
|
||||
{
|
||||
icon: <Phone className="w-12 h-12 text-blue-500" />,
|
||||
title: translate('::Public.features.mobil'),
|
||||
description: translate('::Public.features.mobil.desc'),
|
||||
},
|
||||
{
|
||||
icon: <BarChart className="w-12 h-12 text-blue-500" />,
|
||||
title: translate('::Public.features.scalable'),
|
||||
description: translate('::Public.features.scalable.desc'),
|
||||
},
|
||||
{
|
||||
icon: <Shield className="w-12 h-12 text-blue-500" />,
|
||||
title: translate('::Public.features.guvenlik'),
|
||||
description: translate('::Public.features.guvenlik.desc'),
|
||||
},
|
||||
]
|
||||
|
||||
const solutions = [
|
||||
{ icon: <Monitor className="w-16 h-16 text-white" />, title: translate('::Public.solutions.web.title'), description: translate('::Public.solutions.web.desc'), color: 'bg-blue-600' },
|
||||
{ icon: <Smartphone className="w-16 h-16 text-white" />, title: translate('::Public.solutions.mobile.title'), description: translate('::Public.solutions.mobile.desc'), color: 'bg-purple-600' },
|
||||
{ icon: <Server className="w-16 h-16 text-white" />, title: translate('::Public.solutions.custom.title'), description: translate('::Public.solutions.custom.desc'), color: 'bg-green-600' },
|
||||
{ icon: <Database className="w-16 h-16 text-white" />, title: translate('::Public.solutions.database.title'), description: translate('::Public.solutions.database.desc'), color: 'bg-red-600' },
|
||||
{
|
||||
icon: <Monitor className="w-16 h-16 text-white" />,
|
||||
title: translate('::Public.solutions.web.title'),
|
||||
description: translate('::Public.solutions.web.desc'),
|
||||
color: 'bg-blue-600',
|
||||
},
|
||||
{
|
||||
icon: <Smartphone className="w-16 h-16 text-white" />,
|
||||
title: translate('::Public.solutions.mobile.title'),
|
||||
description: translate('::Public.solutions.mobile.desc'),
|
||||
color: 'bg-purple-600',
|
||||
},
|
||||
{
|
||||
icon: <Server className="w-16 h-16 text-white" />,
|
||||
title: translate('::Public.solutions.custom.title'),
|
||||
description: translate('::Public.solutions.custom.desc'),
|
||||
color: 'bg-green-600',
|
||||
},
|
||||
{
|
||||
icon: <Database className="w-16 h-16 text-white" />,
|
||||
title: translate('::Public.solutions.database.title'),
|
||||
description: translate('::Public.solutions.database.desc'),
|
||||
color: 'bg-red-600',
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="min-h-screen">
|
||||
<Helmet
|
||||
titleTemplate="%s | Sözsoft"
|
||||
title={translate('::' + 'App.Home')}
|
||||
defaultTitle="Sözsoft"
|
||||
></Helmet>
|
||||
|
||||
{/* Hero */}
|
||||
<div className="relative min-h-screen">
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-blue-900 via-indigo-900 to-purple-900"></div>
|
||||
<div className="absolute inset-0 opacity-20" style={{ backgroundImage: 'url("https://images.pexels.com/photos/3183150/pexels-photo-3183150.jpeg?auto=compress&cs=tinysrgb&w=1920")', backgroundSize: 'cover', backgroundPosition: 'center' }}></div>
|
||||
<div
|
||||
className="absolute inset-0 opacity-20"
|
||||
style={{
|
||||
backgroundImage:
|
||||
'url("https://images.pexels.com/photos/3183150/pexels-photo-3183150.jpeg?auto=compress&cs=tinysrgb&w=1920")',
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
}}
|
||||
></div>
|
||||
|
||||
<div className="relative container mx-auto px-4 pt-32 pb-16">
|
||||
<div className="max-w-4xl mx-auto text-center">
|
||||
<h1 className="text-3xl md:text-5xl font-bold mb-6 text-white">{translate('::Public.hero.title')}</h1>
|
||||
<p className="text-xl md:text-2xl text-gray-300 mb-12">{translate('::Public.hero.subtitle')}</p>
|
||||
<h1 className="text-3xl md:text-5xl font-bold mb-6 text-white">
|
||||
{translate('::Public.hero.title')}
|
||||
</h1>
|
||||
<p className="text-xl md:text-2xl text-gray-300 mb-12">
|
||||
{translate('::Public.hero.subtitle')}
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col md:flex-row justify-center gap-6 mb-16">
|
||||
<Link to={ROUTES_ENUM.public.contact} className="inline-flex items-center justify-center px-8 py-4 bg-gradient-to-r from-blue-500 to-purple-500 hover:from-blue-600 hover:to-purple-600 text-white rounded-lg font-semibold transition-all transform hover:scale-105">
|
||||
{translate('::Public.hero.cta.consultation')} <ArrowRight className="ml-2" size={20} />
|
||||
<Link
|
||||
to={ROUTES_ENUM.public.contact}
|
||||
className="inline-flex items-center justify-center px-8 py-4 bg-gradient-to-r from-blue-500 to-purple-500 hover:from-blue-600 hover:to-purple-600 text-white rounded-lg font-semibold transition-all transform hover:scale-105"
|
||||
>
|
||||
{translate('::Public.hero.cta.consultation')}{' '}
|
||||
<ArrowRight className="ml-2" size={20} />
|
||||
</Link>
|
||||
<Link to={ROUTES_ENUM.public.products} className="inline-flex items-center justify-center px-8 py-4 bg-white/10 hover:bg-white/20 text-white rounded-lg font-semibold backdrop-blur-sm transition-all transform hover:scale-105">
|
||||
<Link
|
||||
to={ROUTES_ENUM.public.products}
|
||||
className="inline-flex items-center justify-center px-8 py-4 bg-white/10 hover:bg-white/20 text-white rounded-lg font-semibold backdrop-blur-sm transition-all transform hover:scale-105"
|
||||
>
|
||||
{translate('::Public.hero.cta.discover')}
|
||||
</Link>
|
||||
</div>
|
||||
|
|
@ -64,17 +141,23 @@ const Home: React.FC = () => {
|
|||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 max-w-4xl mx-auto">
|
||||
<div className="bg-white/5 backdrop-blur-sm rounded-2xl p-8 text-center hover:scale-105 hover:bg-white/10 transition-all">
|
||||
<Calendar className="mx-auto mb-4 text-blue-400" size={40} />
|
||||
<h3 className="text-xl font-semibold mb-3 text-white">{translate('::Public.hero.service1.title')}</h3>
|
||||
<h3 className="text-xl font-semibold mb-3 text-white">
|
||||
{translate('::Public.hero.service1.title')}
|
||||
</h3>
|
||||
<p className="text-gray-300">{translate('::Public.hero.service1.desc')}</p>
|
||||
</div>
|
||||
<div className="bg-white/5 backdrop-blur-sm rounded-2xl p-8 text-center hover:scale-105 hover:bg-white/10 transition-all">
|
||||
<Users className="mx-auto mb-4 text-purple-400" size={40} />
|
||||
<h3 className="text-xl font-semibold mb-3 text-white">{translate('::Public.hero.service2.title')}</h3>
|
||||
<h3 className="text-xl font-semibold mb-3 text-white">
|
||||
{translate('::Public.hero.service2.title')}
|
||||
</h3>
|
||||
<p className="text-gray-300">{translate('::Public.hero.service2.desc')}</p>
|
||||
</div>
|
||||
<div className="bg-white/5 backdrop-blur-sm rounded-2xl p-8 text-center hover:scale-105 hover:bg-white/10 transition-all">
|
||||
<Shield className="mx-auto mb-4 text-indigo-400" size={40} />
|
||||
<h3 className="text-xl font-semibold mb-3 text-white">{translate('::Public.hero.service3.title')}</h3>
|
||||
<h3 className="text-xl font-semibold mb-3 text-white">
|
||||
{translate('::Public.hero.service3.title')}
|
||||
</h3>
|
||||
<p className="text-gray-300">{translate('::Public.hero.service3.desc')}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -86,13 +169,20 @@ const Home: React.FC = () => {
|
|||
<section className="py-20 bg-white">
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="text-4xl font-bold text-gray-900 mb-4">{translate('::Public.features.title')}</h2>
|
||||
<p className="text-xl text-gray-600 max-w-2xl mx-auto">{translate('::Public.features.subtitle')}</p>
|
||||
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||
{translate('::Public.features.title')}
|
||||
</h2>
|
||||
<p className="text-xl text-gray-600 max-w-2xl mx-auto">
|
||||
{translate('::Public.features.subtitle')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
|
||||
{features.map((feature, i) => (
|
||||
<div key={i} className="p-8 bg-white rounded-xl shadow-lg hover:shadow-xl transition-shadow">
|
||||
<div
|
||||
key={i}
|
||||
className="p-8 bg-white rounded-xl shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<div className="mb-6">{feature.icon}</div>
|
||||
<h3 className="text-xl font-semibold text-gray-900 mb-4">{feature.title}</h3>
|
||||
<p className="text-gray-600">{feature.description}</p>
|
||||
|
|
@ -106,13 +196,20 @@ const Home: React.FC = () => {
|
|||
<section className="py-20 bg-gray-50">
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="text-4xl font-bold text-gray-900 mb-4">{translate('::Public.solutions.title')}</h2>
|
||||
<p className="text-xl text-gray-600 max-w-2xl mx-auto">{translate('::Public.solutions.subtitle')}</p>
|
||||
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||
{translate('::Public.solutions.title')}
|
||||
</h2>
|
||||
<p className="text-xl text-gray-600 max-w-2xl mx-auto">
|
||||
{translate('::Public.solutions.subtitle')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
|
||||
{solutions.map((s, i) => (
|
||||
<div key={i} className="group relative overflow-hidden rounded-2xl transition-all hover:scale-105">
|
||||
<div
|
||||
key={i}
|
||||
className="group relative overflow-hidden rounded-2xl transition-all hover:scale-105"
|
||||
>
|
||||
<div className={`${s.color} p-8 h-full`}>
|
||||
<div className="mb-6">{s.icon}</div>
|
||||
<h3 className="text-2xl font-semibold text-white mb-4">{s.title}</h3>
|
||||
|
|
@ -127,9 +224,14 @@ const Home: React.FC = () => {
|
|||
{/* Call to Action */}
|
||||
<section className="bg-blue-600 py-16">
|
||||
<div className="container mx-auto px-4 text-center">
|
||||
<h2 className="text-3xl font-bold text-white mb-4">{translate('::Public.common.getStarted')}</h2>
|
||||
<h2 className="text-3xl font-bold text-white mb-4">
|
||||
{translate('::Public.common.getStarted')}
|
||||
</h2>
|
||||
<p className="text-white text-lg mb-8">{translate('::Public.common.contact')}</p>
|
||||
<Link to={ROUTES_ENUM.public.contact} className="bg-white text-blue-600 px-8 py-3 rounded-lg font-semibold hover:bg-blue-50 transition-colors">
|
||||
<Link
|
||||
to={ROUTES_ENUM.public.contact}
|
||||
className="bg-white text-blue-600 px-8 py-3 rounded-lg font-semibold hover:bg-blue-50 transition-colors"
|
||||
>
|
||||
{translate('::Public.common.learnMore')}
|
||||
</Link>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ import {
|
|||
removeItemFromCart,
|
||||
updateCartItemQuantity,
|
||||
} from '@/utils/cartUtils'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
const Payment: React.FC = () => {
|
||||
|
|
@ -18,6 +20,7 @@ const Payment: React.FC = () => {
|
|||
const [tenant, setTenant] = useState<CustomTenantDto | null>(null)
|
||||
const [isCartOpen, setIsCartOpen] = useState(false)
|
||||
const [cartState, setCartState] = useState<CartState>(initialCartState)
|
||||
const { translate } = useLocalization()
|
||||
|
||||
useEffect(() => {
|
||||
const tenantData = localStorage.getItem('tenantData') // ✅ güncellendi
|
||||
|
|
@ -109,6 +112,12 @@ const Payment: React.FC = () => {
|
|||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50">
|
||||
<Helmet
|
||||
titleTemplate="%s | Sözsoft"
|
||||
title={translate('::' + 'Public.nav.payment')}
|
||||
defaultTitle="Sözsoft"
|
||||
></Helmet>
|
||||
|
||||
{/* Hero Section */}
|
||||
<div className="relative bg-blue-900 text-white py-12">
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -11,12 +11,16 @@ import {
|
|||
setCartGlobalPeriod,
|
||||
updateCartItemQuantity,
|
||||
} from '@/utils/cartUtils'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
const Products: React.FC = () => {
|
||||
const [searchQuery, setSearchQuery] = useState('')
|
||||
const [isCartOpen, setIsCartOpen] = useState(false)
|
||||
const { translate } = useLocalization()
|
||||
|
||||
const [cartState, setCartState] = useState<CartState>(() => {
|
||||
// Load cart state from localStorage if available
|
||||
const savedCart = localStorage.getItem('cartState')
|
||||
|
|
@ -70,6 +74,12 @@ const Products: React.FC = () => {
|
|||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50">
|
||||
<Helmet
|
||||
titleTemplate="%s | Sözsoft"
|
||||
title={translate('::' + 'Public.nav.products')}
|
||||
defaultTitle="Sözsoft"
|
||||
></Helmet>
|
||||
|
||||
{/* Hero Section */}
|
||||
<div className="relative bg-blue-900 text-white py-12">
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -1,16 +1,9 @@
|
|||
import React from "react";
|
||||
import {
|
||||
Code2,
|
||||
Globe2,
|
||||
Server,
|
||||
Users,
|
||||
Shield,
|
||||
Settings,
|
||||
CheckCircle,
|
||||
} from "lucide-react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { useLocalization } from "@/utils/hooks/useLocalization";
|
||||
import { ROUTES_ENUM } from "@/routes/route.constant";
|
||||
import React from 'react'
|
||||
import { Code2, Globe2, Server, Users, Shield, Settings, CheckCircle } from 'lucide-react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||
import { Helmet } from 'react-helmet'
|
||||
|
||||
const Services: React.FC = () => {
|
||||
const { translate } = useLocalization()
|
||||
|
|
@ -88,7 +81,7 @@ const Services: React.FC = () => {
|
|||
translate('::Public.services.consulting.features.training'),
|
||||
],
|
||||
},
|
||||
];
|
||||
]
|
||||
|
||||
const supportPlans = [
|
||||
{
|
||||
|
|
@ -127,10 +120,16 @@ const Services: React.FC = () => {
|
|||
translate('::Public.services.support.sms.features.api'),
|
||||
],
|
||||
},
|
||||
];
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50">
|
||||
<Helmet
|
||||
titleTemplate="%s | Sözsoft"
|
||||
title={translate('::' + 'Public.nav.services')}
|
||||
defaultTitle="Sözsoft"
|
||||
></Helmet>
|
||||
|
||||
{/* Hero Section */}
|
||||
<div className="relative bg-blue-900 text-white py-12">
|
||||
<div
|
||||
|
|
@ -138,12 +137,14 @@ const Services: React.FC = () => {
|
|||
style={{
|
||||
backgroundImage:
|
||||
'url("https://images.pexels.com/photos/3183173/pexels-photo-3183173.jpeg?auto=compress&cs=tinysrgb&w=1920")',
|
||||
backgroundSize: "cover",
|
||||
backgroundPosition: "center",
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
}}
|
||||
></div>
|
||||
<div className="container mx-auto pt-20 relative">
|
||||
<h1 className="text-5xl font-bold ml-4 mt-3 mb-2 text-white">{translate('::Public.services.title')}</h1>
|
||||
<h1 className="text-5xl font-bold ml-4 mt-3 mb-2 text-white">
|
||||
{translate('::Public.services.title')}
|
||||
</h1>
|
||||
<p className="text-xl max-w-3xl ml-4">{translate('::Public.services.subtitle')}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -158,16 +159,11 @@ const Services: React.FC = () => {
|
|||
className="bg-white rounded-xl shadow-lg p-8 hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<div className="mb-6">{service.icon}</div>
|
||||
<h3 className="text-2xl font-bold text-gray-900 mb-4">
|
||||
{service.title}
|
||||
</h3>
|
||||
<h3 className="text-2xl font-bold text-gray-900 mb-4">{service.title}</h3>
|
||||
<p className="text-gray-600 mb-6">{service.description}</p>
|
||||
<ul className="space-y-2">
|
||||
{service.features.map((feature, fIndex) => (
|
||||
<li
|
||||
key={fIndex}
|
||||
className="flex items-center text-gray-700"
|
||||
>
|
||||
<li key={fIndex} className="flex items-center text-gray-700">
|
||||
<span className="w-2 h-2 bg-blue-600 rounded-full mr-2"></span>
|
||||
{feature}
|
||||
</li>
|
||||
|
|
@ -187,18 +183,12 @@ const Services: React.FC = () => {
|
|||
</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{supportPlans.map((plan, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="bg-white rounded-xl shadow-lg p-8 border border-gray-200"
|
||||
>
|
||||
<div key={index} className="bg-white rounded-xl shadow-lg p-8 border border-gray-200">
|
||||
<h3 className="text-xl font-bold mb-4">{plan.title}</h3>
|
||||
|
||||
<ul className="space-y-3 mb-8">
|
||||
{plan.features.map((feature, fIndex) => (
|
||||
<li
|
||||
key={fIndex}
|
||||
className="flex items-center space-x-2 text-gray-700"
|
||||
>
|
||||
<li key={fIndex} className="flex items-center space-x-2 text-gray-700">
|
||||
<CheckCircle className="w-5 h-5 text-green-500 flex-shrink-0" />
|
||||
<span>{feature}</span>
|
||||
</li>
|
||||
|
|
@ -219,7 +209,9 @@ const Services: React.FC = () => {
|
|||
{/* Call to Action */}
|
||||
<div className="bg-blue-900 text-white py-16">
|
||||
<div className="container mx-auto px-4 text-center">
|
||||
<h2 className="text-3xl font-bold mb-6 text-white">{translate('::Public.services.cta.title')}</h2>
|
||||
<h2 className="text-3xl font-bold mb-6 text-white">
|
||||
{translate('::Public.services.cta.title')}
|
||||
</h2>
|
||||
<p className="text-xl mb-8 max-w-2xl mx-auto">
|
||||
{translate('::Public.services.cta.description')}
|
||||
</p>
|
||||
|
|
@ -232,7 +224,7 @@ const Services: React.FC = () => {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default Services;
|
||||
export default Services
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
import { OrderSuccess } from '@/components/orders/OrderSuccess'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
const Success: React.FC = () => {
|
||||
const navigate = useNavigate()
|
||||
const [orderId, setOrderId] = useState<string>('')
|
||||
const { translate } = useLocalization()
|
||||
|
||||
useEffect(() => {
|
||||
// Get order ID from local storage
|
||||
|
|
@ -28,6 +31,11 @@ const Success: React.FC = () => {
|
|||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50">
|
||||
<Helmet
|
||||
titleTemplate="%s | Sözsoft"
|
||||
title={translate('::' + 'Public.nav.success')}
|
||||
defaultTitle="Sözsoft"
|
||||
></Helmet>
|
||||
<div className="relative bg-blue-900 text-white py-12">
|
||||
<div
|
||||
className="absolute inset-0 opacity-20"
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ const Settings = () => {
|
|||
<Container className="h-full">
|
||||
<Helmet
|
||||
titleTemplate="%s | Kurs Platform"
|
||||
title={translate('::' + 'Settings')}
|
||||
title={translate('::' + 'App.Settings')}
|
||||
defaultTitle="Kurs Platform"
|
||||
></Helmet>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue