Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19c50693e4 | ||
|
|
0187796388 |
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "smoke-tracker",
|
||||
"version": "1.1.0",
|
||||
"version": "1.1.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "smoke-tracker",
|
||||
"version": "1.1.0",
|
||||
"version": "1.1.1",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@brojs/cli": "^1.10.0",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "smoke-tracker",
|
||||
"version": "1.1.0",
|
||||
"version": "1.1.1",
|
||||
"description": "",
|
||||
"main": "./src/index.tsx",
|
||||
"scripts": {
|
||||
|
||||
162
src/components/CigaretteLoader.tsx
Normal file
162
src/components/CigaretteLoader.tsx
Normal file
@ -0,0 +1,162 @@
|
||||
import React from 'react'
|
||||
|
||||
export const CigaretteLoader = () => (
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
height: '100vh',
|
||||
backgroundColor: '#1a1a1a'
|
||||
}}>
|
||||
<svg width="200" height="60" viewBox="0 0 200 60" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
{/* Градиент для сигареты */}
|
||||
<linearGradient id="cigaretteGradient" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" style={{ stopColor: '#f5f5f5', stopOpacity: 1 }} />
|
||||
<stop offset="95%" style={{ stopColor: '#e0e0e0', stopOpacity: 1 }} />
|
||||
<stop offset="100%" style={{ stopColor: '#d4a574', stopOpacity: 1 }} />
|
||||
</linearGradient>
|
||||
|
||||
{/* Градиент для тлеющей части */}
|
||||
<linearGradient id="burningGradient" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" style={{ stopColor: '#ff6b35', stopOpacity: 1 }} />
|
||||
<stop offset="50%" style={{ stopColor: '#ff8c42', stopOpacity: 1 }} />
|
||||
<stop offset="100%" style={{ stopColor: '#ffa600', stopOpacity: 1 }} />
|
||||
</linearGradient>
|
||||
|
||||
{/* Маска для эффекта сгорания */}
|
||||
<mask id="burnMask">
|
||||
<rect x="0" y="0" width="200" height="60" fill="white">
|
||||
<animate
|
||||
attributeName="width"
|
||||
from="0"
|
||||
to="200"
|
||||
dur="2s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</rect>
|
||||
</mask>
|
||||
</defs>
|
||||
|
||||
{/* Тело сигареты (не сгоревшая часть) */}
|
||||
<rect x="0" y="22" width="180" height="16" rx="2" fill="url(#cigaretteGradient)" />
|
||||
|
||||
{/* Фильтр */}
|
||||
<rect x="175" y="20" width="20" height="20" rx="2" fill="#d4a574" />
|
||||
<line x1="180" y1="20" x2="180" y2="40" stroke="#b8956a" strokeWidth="1" />
|
||||
<line x1="185" y1="20" x2="185" y2="40" stroke="#b8956a" strokeWidth="1" />
|
||||
<line x1="190" y1="20" x2="190" y2="40" stroke="#b8956a" strokeWidth="1" />
|
||||
|
||||
{/* Сгоревшая часть с маской */}
|
||||
<g mask="url(#burnMask)">
|
||||
<rect x="0" y="22" width="180" height="16" fill="#333" opacity="0.8" />
|
||||
|
||||
{/* Тлеющий край */}
|
||||
<rect x="0" y="24" width="5" height="12" fill="url(#burningGradient)">
|
||||
<animate
|
||||
attributeName="x"
|
||||
from="0"
|
||||
to="180"
|
||||
dur="2s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</rect>
|
||||
|
||||
{/* Искры */}
|
||||
<circle r="2" fill="#ff6b35">
|
||||
<animate
|
||||
attributeName="cx"
|
||||
from="5"
|
||||
to="185"
|
||||
dur="2s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
<animate
|
||||
attributeName="cy"
|
||||
values="20;18;20"
|
||||
dur="0.3s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
values="1;0.5;1"
|
||||
dur="0.3s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</circle>
|
||||
<circle r="1.5" fill="#ffa600">
|
||||
<animate
|
||||
attributeName="cx"
|
||||
from="8"
|
||||
to="188"
|
||||
dur="2s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
<animate
|
||||
attributeName="cy"
|
||||
values="40;42;40"
|
||||
dur="0.4s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
values="0.8;0.3;0.8"
|
||||
dur="0.4s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</circle>
|
||||
</g>
|
||||
|
||||
{/* Дым */}
|
||||
<g opacity="0.6">
|
||||
<ellipse rx="3" ry="3" fill="#888">
|
||||
<animate
|
||||
attributeName="cx"
|
||||
from="5"
|
||||
to="185"
|
||||
dur="2s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
<animate
|
||||
attributeName="cy"
|
||||
from="18"
|
||||
to="8"
|
||||
dur="1s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
from="0.6"
|
||||
to="0"
|
||||
dur="1s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</ellipse>
|
||||
<ellipse rx="4" ry="4" fill="#999">
|
||||
<animate
|
||||
attributeName="cx"
|
||||
from="3"
|
||||
to="183"
|
||||
dur="2s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
<animate
|
||||
attributeName="cy"
|
||||
from="18"
|
||||
to="5"
|
||||
dur="1.2s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
from="0.5"
|
||||
to="0"
|
||||
dur="1.2s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</ellipse>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -7,9 +7,12 @@ import { SignInPage, SignUpPage } from './pages/auth'
|
||||
import { TrackerPage } from './pages/tracker'
|
||||
import { StatsPage } from './pages/stats'
|
||||
import { ProtectedRoute } from './components/ProtectedRoute'
|
||||
import { CigaretteLoader } from './components/CigaretteLoader'
|
||||
|
||||
const PageWrapper = ({ children }: React.PropsWithChildren) => (
|
||||
<Suspense fallback={<div>Loading...</div>}>{children}</Suspense>
|
||||
<Suspense fallback={<CigaretteLoader />}>
|
||||
{children}
|
||||
</Suspense>
|
||||
)
|
||||
|
||||
export const Dashboard = () => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user