index.tsx 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import React from "react";
  2. import useStored from "src/store/useStored";
  3. import styled from "styled-components";
  4. async function getSponsors() {
  5. try {
  6. const res = await fetch("https://ghs.vercel.app/sponsors/aykutsarac");
  7. const data = await res.json();
  8. if (data.sponsors) {
  9. return data.sponsors.map(user => ({
  10. handle: user.handle,
  11. avatar: user.avatar,
  12. profile: user.profile,
  13. }));
  14. }
  15. return [];
  16. } catch (error) {
  17. console.error(error);
  18. return [];
  19. }
  20. }
  21. const StyledSponsorsWrapper = styled.ul`
  22. display: flex;
  23. width: 70%;
  24. margin: 0;
  25. padding: 0;
  26. list-style: none;
  27. gap: 10px;
  28. flex-wrap: wrap;
  29. align-items: center;
  30. justify-content: center;
  31. `;
  32. const StyledSponsor = styled.li<{ handle: string }>`
  33. display: flex;
  34. justify-content: center;
  35. position: relative;
  36. &:hover {
  37. &::before {
  38. content: "${({ handle }) => handle}";
  39. position: absolute;
  40. top: 0;
  41. background: ${({ theme }) => theme.BACKGROUND_PRIMARY};
  42. transform: translateY(-130%);
  43. padding: 6px 8px;
  44. border-radius: 4px;
  45. font-weight: 500;
  46. font-size: 14px;
  47. color: ${({ theme }) => theme.TEXT_NORMAL};
  48. }
  49. &::after {
  50. content: "";
  51. position: absolute;
  52. top: 0;
  53. transform: translateY(-110%);
  54. border-width: 5px;
  55. border-style: solid;
  56. border-color: ${({ theme }) => theme.BACKGROUND_PRIMARY} transparent transparent transparent;
  57. }
  58. }
  59. img {
  60. border-radius: 100%;
  61. }
  62. `;
  63. export const Sponsors = () => {
  64. const { sponsors, setSponsors } = useStored();
  65. React.useEffect(() => {
  66. if (!sponsors?.nextDate || sponsors?.nextDate < Date.now()) {
  67. getSponsors().then(setSponsors);
  68. }
  69. }, [setSponsors, sponsors?.nextDate]);
  70. if (!sponsors?.users?.length) return null;
  71. return (
  72. <StyledSponsorsWrapper>
  73. {sponsors.users.map(user => (
  74. <StyledSponsor handle={user.handle} key={user.handle}>
  75. <a href={user.profile} target="_blank" rel="noreferrer">
  76. <img src={user.avatar} alt={user.handle} width="40" height="40" loading="lazy" />
  77. </a>
  78. </StyledSponsor>
  79. ))}
  80. </StyledSponsorsWrapper>
  81. );
  82. };