mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-06 03:34:40 +00:00
add store page
This commit is contained in:
@@ -70,6 +70,7 @@
|
|||||||
"react-shadow": "^20.4.0",
|
"react-shadow": "^20.4.0",
|
||||||
"rimraf": "^5.0.5",
|
"rimraf": "^5.0.5",
|
||||||
"sortablejs": "^1.15.2",
|
"sortablejs": "^1.15.2",
|
||||||
|
"swiper": "^11.1.0",
|
||||||
"tailwindcss": "^3.4.1",
|
"tailwindcss": "^3.4.1",
|
||||||
"ts-loader": "^9.5.1",
|
"ts-loader": "^9.5.1",
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import logo from '../../../resources/icons/betterseqta-dark-full.png';
|
||||||
|
import logoDark from '../../../resources/icons/betterseqta-light-full.png';
|
||||||
|
|
||||||
|
export default function header({ searchTerm, setSearchTerm }: { searchTerm: string, setSearchTerm: (value: string) => void }) {
|
||||||
|
return <header className="sticky top-0 z-50 w-full bg-white border-b shadow-md border-b-white/10 dark:bg-zinc-800">
|
||||||
|
<div className="flex items-center justify-between px-4 py-1">
|
||||||
|
<img src={logo} className="h-16 dark:hidden" />
|
||||||
|
<img src={logoDark} className="hidden h-16 dark:block" />
|
||||||
|
<div className="relative">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Search themes..."
|
||||||
|
value={searchTerm}
|
||||||
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
|
className="px-4 py-2 pl-10 bg-gray-100 rounded-full dark:bg-zinc-700 dark:text-gray-100 focus:outline-none focus:border-transparent" />
|
||||||
|
<svg
|
||||||
|
className="absolute w-5 h-5 text-gray-400 transform -translate-y-1/2 left-3 top-1/2 dark:text-gray-200"
|
||||||
|
fill="none"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>;
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>BetterSEQTA+ Settings</title>
|
<title>BetterSEQTA+ Settings</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body class="dark:bg-zinc-900">
|
||||||
<div id="ExtensionPopup"></div>
|
<div id="ExtensionPopup"></div>
|
||||||
<script type="module" src="./main.tsx"></script>
|
<script type="module" src="./main.tsx"></script>
|
||||||
<script type="module" src="./dark.ts"></script>
|
<script type="module" src="./dark.ts"></script>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import ThemeCreator from './pages/ThemeCreator';
|
|||||||
import Store from './pages/Store';
|
import Store from './pages/Store';
|
||||||
|
|
||||||
browser.storage.local.get().then(({ telemetry, DarkMode }) => {
|
browser.storage.local.get().then(({ telemetry, DarkMode }) => {
|
||||||
if (DarkMode) document.body.classList.add('dark');
|
if (DarkMode) document.documentElement.classList.add('dark');
|
||||||
|
|
||||||
if (telemetry === true)
|
if (telemetry === true)
|
||||||
Sentry.init({
|
Sentry.init({
|
||||||
|
|||||||
@@ -1,9 +1,112 @@
|
|||||||
|
import { useRef, useState } from 'react';
|
||||||
|
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||||
|
import { Scrollbar, Autoplay } from 'swiper/modules';
|
||||||
|
import Header from '../components/store/header';
|
||||||
|
|
||||||
|
import 'swiper/css';
|
||||||
|
import 'swiper/css/pagination';
|
||||||
|
import 'swiper/css/scrollbar';
|
||||||
|
import 'swiper/css/autoplay';
|
||||||
|
|
||||||
const Store = () => {
|
const Store = () => {
|
||||||
return (
|
const [searchTerm, setSearchTerm] = useState('');
|
||||||
<div>
|
const swiperCover = useRef<any | null>(null);
|
||||||
<h2>Store</h2>
|
|
||||||
</div>
|
const coverThemes = [
|
||||||
)
|
{
|
||||||
|
coverImage: 'https://via.placeholder.com/300x200',
|
||||||
|
name: 'Theme Name',
|
||||||
|
description: 'Theme description goes here.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
coverImage: 'https://via.placeholder.com/300x200',
|
||||||
|
name: 'Theme Name',
|
||||||
|
description: 'Theme description goes here.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
coverImage: 'https://via.placeholder.com/300x200',
|
||||||
|
name: 'Theme Name',
|
||||||
|
description: 'Theme description goes here.'
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-screen h-screen overflow-y-scroll bg-zinc-100 dark:bg-zinc-900">
|
||||||
|
|
||||||
|
<Header searchTerm={searchTerm} setSearchTerm={setSearchTerm} />
|
||||||
|
|
||||||
|
<div className="px-32 py-12">
|
||||||
|
<div className="relative w-full bg-green-100 aspect-[8/3] rounded-xl overflow-clip">
|
||||||
|
<Swiper
|
||||||
|
ref={swiperCover}
|
||||||
|
spaceBetween={0}
|
||||||
|
slidesPerView={1}
|
||||||
|
modules={[Scrollbar, Autoplay]}
|
||||||
|
navigation
|
||||||
|
autoplay={{
|
||||||
|
delay: 5000,
|
||||||
|
disableOnInteraction: false,
|
||||||
|
pauseOnMouseEnter: true
|
||||||
|
}}
|
||||||
|
pagination={{ clickable: true }}
|
||||||
|
scrollbar={{ draggable: true }}
|
||||||
|
onSlideChange={() => console.log('slide change')}
|
||||||
|
onSwiper={(swiper) => console.log(swiper)}
|
||||||
|
>
|
||||||
|
{ coverThemes.map((theme, index) => (
|
||||||
|
<SwiperSlide key={index}>
|
||||||
|
<img
|
||||||
|
src={theme.coverImage}
|
||||||
|
alt="Theme Preview"
|
||||||
|
className="object-cover w-full h-full"
|
||||||
|
/>
|
||||||
|
</SwiperSlide>
|
||||||
|
)) }
|
||||||
|
</Swiper>
|
||||||
|
|
||||||
|
{/* pagination */}
|
||||||
|
<div className='absolute z-10 flex gap-2 bottom-2 right-2'>
|
||||||
|
|
||||||
|
<button onClick={ () => {swiperCover.current?.swiper.slidePrev() }} className='flex items-center justify-center w-8 h-8 text-white bg-black bg-opacity-50 rounded-full dark:bg-zinc-800 dark:bg-opacity-50'>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" d="m15.75 19.5-7.5-7.5 7.5-7.5" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button onClick={ () => {swiperCover.current?.swiper.slideNext() }} className='flex items-center justify-center w-8 h-8 text-white bg-black bg-opacity-50 rounded-full dark:bg-zinc-800 dark:bg-opacity-50'>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 gap-8 px-4 py-8 mx-auto max-w-7xl sm:px-6 lg:px-8 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
|
||||||
|
{
|
||||||
|
Array.from({ length: 30 }).map((_, index) => (
|
||||||
|
<div key={index} className="overflow-hidden bg-white rounded-lg shadow-md dark:bg-zinc-800">
|
||||||
|
<img
|
||||||
|
src="https://via.placeholder.com/300x200"
|
||||||
|
alt="Theme Preview"
|
||||||
|
className="object-cover w-full h-48"
|
||||||
|
/>
|
||||||
|
<div className="p-4">
|
||||||
|
<h3 className="text-xl font-bold text-gray-900 dark:text-gray-100">
|
||||||
|
Theme Name
|
||||||
|
</h3>
|
||||||
|
<p className="mt-2 text-gray-600 dark:text-gray-400">
|
||||||
|
Theme description goes here.
|
||||||
|
</p>
|
||||||
|
<button className="px-4 py-2 mt-4 text-white bg-blue-500 rounded-full hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
|
||||||
|
Install
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default Store;
|
export default Store;
|
||||||
Reference in New Issue
Block a user