Skip to content

Commit

Permalink
Merge pull request #16 from shampsdev:dev
Browse files Browse the repository at this point in the history
added stats, refactored
  • Loading branch information
mikedegeofroy authored Oct 15, 2024
2 parents 873aa74 + 17e20b3 commit e52a2dc
Show file tree
Hide file tree
Showing 11 changed files with 299 additions and 24 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
BACKEND_URL='api.shamps.dev'
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# ...
.next
next-env.d.ts
.env

logs
*.log
Expand Down
30 changes: 30 additions & 0 deletions app/api/stats.get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { client } from '@/instances/ghql.instance';
import { Stat } from '@/types/stat.interface';
import { gql } from '@apollo/client';

interface StatQuery {
stats: Stat[];
}

const GET_INITIAL_STATS = gql`
query {
stats {
stat_id
name
count
timestamp
}
}
`;

export const getStats = async () => {
try {
const response = client.query<StatQuery>({
query: GET_INITIAL_STATS,
});

return response;
} catch (error) {
console.error('Error fetching initial stats:', error);
}
};
25 changes: 25 additions & 0 deletions app/api/stats.ws.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Stat } from '@/types/stat.interface';
import { gql, useSubscription } from '@apollo/client';

export interface StatSubscription {
statCreated: Stat[];
}

const STAT_CREATED_SUBSCRIPTION = gql`
subscription {
statCreated {
stat_id
name
count
timestamp
}
}
`;

export const useStats = () => {
const { data, loading } = useSubscription<StatSubscription>(
STAT_CREATED_SUBSCRIPTION
);

return { data, loading };
};
14 changes: 14 additions & 0 deletions app/instances/ghql.instance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { ApolloClient, InMemoryCache } from '@apollo/client';
import { WebSocketLink } from '@apollo/client/link/ws';
import { SubscriptionClient } from 'subscriptions-transport-ws';

const wsLink = new WebSocketLink(
new SubscriptionClient(`ws://${process.env.BACKEND_URL}/graphql`, {
reconnect: true,
})
);

export const client = new ApolloClient({
link: wsLink,
cache: new InMemoryCache(),
});
47 changes: 32 additions & 15 deletions app/modules/footer.section.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { getStats } from '@/api/stats.get';
import { useStats } from '@/api/stats.ws';
import { Footer } from '@/components/footer';
import { Icons } from '@/components/icons';
import { NewsTicker } from '@/components/news-ticker';
import { News } from '@/types/news.interface';
import { useEffect, useState } from 'react';

const telegram_stats: News[] = [
{
Expand All @@ -19,25 +22,39 @@ const telegram_stats: News[] = [
},
];

const stats: News[] = [
{
icon: <Icons.dino />,
title: '1203 коммита',
},
{
icon: <Icons.time />,
title: '34 ночей без сна',
},
{
icon: <Icons.coffee />,
title: '603 выпитых кружек кофе',
},
];
const iconMapping: Record<string, JSX.Element> = {
coffee_cups: <Icons.coffee />,
sleepless_nights: <Icons.time />,
commits: <Icons.dino />,
};

export const FooterSection = () => {
const { data } = useStats();
const [initialStats, setInitialStats] = useState<News[]>([]);

useEffect(() => {
const fetchInitialStats = async () => {
const response = await getStats();
const statsWithIcons = response?.data.stats.map((stat) => ({
icon: iconMapping[stat.stat_id] || <>?</>,
title: `${stat.count} ${stat.name}`,
}));
if (statsWithIcons) setInitialStats(statsWithIcons);
};

fetchInitialStats();
}, []);

const statsWithIcons: News[] = data?.statCreated
? data.statCreated.map((stat) => ({
icon: iconMapping[stat.stat_id] || <>?</>,
title: `${stat.count} ${stat.name}`,
}))
: initialStats;

return (
<div className='pt-24'>
<NewsTicker newsTop={stats} newsBottom={telegram_stats} />
<NewsTicker newsTop={statsWithIcons} newsBottom={telegram_stats} />
<Footer />
</div>
);
Expand Down
6 changes: 4 additions & 2 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ import { HomePage } from '@/pages/home.page';
import { useLoadingStatus } from '@/hooks/useLoadingStatus';
import Preloader from '@/components/preloader';
import { LoadingStates } from './types/loading-states.enum';
import { ApolloProvider } from '@apollo/client';
import { client } from './instances/ghql.instance';

function App() {
const { loadingStatus } = useLoadingStatus();

return (
<>
<ApolloProvider client={client}>
{loadingStatus === LoadingStates.LOADING ? <Preloader /> : <HomePage />}
</>
</ApolloProvider>
);
}

Expand Down
6 changes: 6 additions & 0 deletions app/types/stat.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface Stat {
count: number;
name: string;
timestamp: Date;
stat_id: string;
}
9 changes: 6 additions & 3 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
const nextConfig = {
output: 'export', // Outputs a Single-Page Application (SPA).
distDir: './dist', // Changes the build output directory to `./dist/`.
}

export default nextConfig
env: {
BACKEND_URL: process.env.BACKEND_URL,
},
};

export default nextConfig;
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@
"start": "next start"
},
"dependencies": {
"@apollo/client": "^3.11.8",
"@radix-ui/react-icons": "^1.3.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"graphql": "^16.9.0",
"lucide-react": "^0.446.0",
"next": "^14.2.15",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-fast-marquee": "^1.6.5",
"subscriptions-transport-ws": "^0.11.0",
"tailwind-merge": "^2.5.2",
"tailwindcss-animate": "^1.0.7"
},
Expand All @@ -37,4 +40,4 @@
"typescript-eslint": "^8.0.1",
"vite": "^5.4.1"
}
}
}
Loading

0 comments on commit e52a2dc

Please sign in to comment.