chore: clean up typings and run prettier on all files
This commit is contained in:
parent
f4ee6adc5b
commit
001e53cc42
|
@ -1,6 +1,5 @@
|
|||
import React, { FunctionComponent } from 'react'
|
||||
import { ViewProps } from 'react-native'
|
||||
// @ts-expect-error No typescript defs
|
||||
import * as Animatable from 'react-native-animatable'
|
||||
|
||||
interface TransitionViewPropsType extends ViewProps {
|
||||
|
|
|
@ -69,10 +69,8 @@ export const LanguageService = {
|
|||
return Strings
|
||||
},
|
||||
|
||||
// @ts-expect-error Fix later, Typecast callback
|
||||
onChange: ({ key }: { key: string }, cb) => {
|
||||
// @ts-expect-error Fix later, Typecast callback
|
||||
changeListeners[`${key}`] = (langCode) => cb(langCode)
|
||||
onChange: ({ key }: { key: string }, cb: (langCode: string) => void) => {
|
||||
changeListeners[key] = (langCode: string) => cb(langCode)
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,9 @@ function replaceNewLines(string: string): string {
|
|||
return string.replace(/\n/g, ' ')
|
||||
}
|
||||
|
||||
export function renderSearchResultPreview(searchResult: MatchData): ReactNode {
|
||||
export function renderSearchResultPreview(
|
||||
searchResult: MatchData<string>
|
||||
): ReactNode {
|
||||
const start = searchResult.match.index
|
||||
const end = start + searchResult.match.length
|
||||
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
// React included automatically in Next.js
|
||||
"react/react-in-jsx-scope": "off",
|
||||
// Allow unescaped characters like '
|
||||
"react/no-unescaped-entities": "off"
|
||||
"react/no-unescaped-entities": "off",
|
||||
"@typescript-eslint/explicit-module-boundary-types": "off"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import screenshotLogin from '../assets/img/screenshots/screenshot_login.png'
|
|||
import SectionTitle from './SectionTitle'
|
||||
import Image from 'next/image'
|
||||
|
||||
const AppShots = (): JSX.Element => {
|
||||
const AppShots = () => {
|
||||
return (
|
||||
<section
|
||||
className="max-w-6xl px-5 py-8 mx-auto md:px-0 md:py-32"
|
||||
|
|
|
@ -14,7 +14,7 @@ import { H1 } from './Typography'
|
|||
import { useIntl } from 'react-intl'
|
||||
import ButtonLink, { ButtonLinkPatreon } from './ButtonLink'
|
||||
|
||||
const Banner = (): JSX.Element => {
|
||||
const Banner = () => {
|
||||
const intl = useIntl()
|
||||
|
||||
return (
|
||||
|
|
|
@ -2,15 +2,26 @@ import classNames from 'classnames'
|
|||
import Link from 'next/link'
|
||||
import { AnchorHTMLAttributes, DetailedHTMLProps } from 'react'
|
||||
|
||||
type ButtonLinkProps = DetailedHTMLProps<AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>
|
||||
type ButtonLinkProps = DetailedHTMLProps<
|
||||
AnchorHTMLAttributes<HTMLAnchorElement>,
|
||||
HTMLAnchorElement
|
||||
>
|
||||
|
||||
const ButtonLink: React.FC<ButtonLinkProps> = ({ children, className, href, target }) => {
|
||||
const isExternal = href?.indexOf("//") !== -1
|
||||
const ButtonLink: React.FC<ButtonLinkProps> = ({
|
||||
children,
|
||||
className,
|
||||
href,
|
||||
target,
|
||||
}) => {
|
||||
const isExternal = href?.indexOf('//') !== -1
|
||||
|
||||
const inner = (
|
||||
<a
|
||||
href={isExternal ? href : undefined}
|
||||
className={classNames('inline-block py-2 px-4 md:px-8 md:py-4 font-bold text-indigo-800 border-2 border-indigo-800 rounded-full hover:bg-indigo-800 dark:hover:bg-indigo-400 hover:text-white dark:text-indigo-400 dark:border-indigo-400', className)}
|
||||
className={classNames(
|
||||
'inline-block py-2 px-4 md:px-8 md:py-4 font-bold text-indigo-800 border-2 border-indigo-800 rounded-full hover:bg-indigo-800 dark:hover:bg-indigo-400 hover:text-white dark:text-indigo-400 dark:border-indigo-400',
|
||||
className
|
||||
)}
|
||||
target={target}
|
||||
rel={target === '_blank' ? 'noopener noreferrer' : ''}
|
||||
>
|
||||
|
|
|
@ -4,7 +4,7 @@ import DownloadButtons from './DownloadButtons'
|
|||
import Section from './Section'
|
||||
import { H2 } from './Typography'
|
||||
|
||||
const CtaThree = (): JSX.Element => {
|
||||
const CtaThree = () => {
|
||||
return (
|
||||
<Section bg="bg-white dark:bg-gray-900">
|
||||
<div>
|
||||
|
|
|
@ -4,7 +4,7 @@ import DownloadButtons from './DownloadButtons'
|
|||
import Section from './Section'
|
||||
import { H2 } from './Typography'
|
||||
|
||||
const CtaTwo = (): JSX.Element => {
|
||||
const CtaTwo = () => {
|
||||
return (
|
||||
<Section>
|
||||
<Image src={img1} width="668" height="500" alt="" />
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import ButtonLink, { ButtonLinkPatreon } from './ButtonLink'
|
||||
|
||||
const DownloadButtons = (): JSX.Element => {
|
||||
const DownloadButtons = () => {
|
||||
return (
|
||||
<div className="space-x-4">
|
||||
<ButtonLink
|
||||
|
|
|
@ -7,12 +7,7 @@ interface FeatureCardProps {
|
|||
isActive: boolean
|
||||
}
|
||||
|
||||
const FeatureCard = ({
|
||||
image,
|
||||
title,
|
||||
text,
|
||||
isActive,
|
||||
}: FeatureCardProps): JSX.Element => {
|
||||
const FeatureCard = ({ image, title, text, isActive }: FeatureCardProps) => {
|
||||
return (
|
||||
<div
|
||||
className={classnames(
|
||||
|
|
|
@ -6,7 +6,7 @@ import { FEATURES_DATA } from './featureData'
|
|||
|
||||
SwiperCore.use([Pagination, Autoplay])
|
||||
|
||||
const Features = (): JSX.Element => {
|
||||
const Features = () => {
|
||||
const swiperParams: SwiperOptions = {
|
||||
slidesPerView: 3,
|
||||
slidesPerGroup: 3,
|
||||
|
|
|
@ -1,33 +1,36 @@
|
|||
import message from '../content/flash.json'
|
||||
|
||||
const Flash = (): JSX.Element => (
|
||||
const Flash = () => (
|
||||
<>
|
||||
{message.subject &&
|
||||
<div className="max-w-6xl mx-auto mt-4">
|
||||
<div className="bg-pink-100 fg-black text-red-800 sm:rounded px-4 py-3 shadow-md" role="alert">
|
||||
<div className="flex space-x-4">
|
||||
<svg
|
||||
className="w-6 h-6 mt-1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
<div className="flex-1">
|
||||
<p className="font-bold">{message.subject}</p>
|
||||
<p className="text-sm">{message.body}</p>
|
||||
{message.subject && (
|
||||
<div className="max-w-6xl mx-auto mt-4">
|
||||
<div
|
||||
className="bg-pink-100 fg-black text-red-800 sm:rounded px-4 py-3 shadow-md"
|
||||
role="alert"
|
||||
>
|
||||
<div className="flex space-x-4">
|
||||
<svg
|
||||
className="w-6 h-6 mt-1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
<div className="flex-1">
|
||||
<p className="font-bold">{message.subject}</p>
|
||||
<p className="text-sm">{message.body}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
)}
|
||||
</>
|
||||
)
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ const team = [
|
|||
{ name: 'Öppna skolplattformen', twitter: 'oppnaskolplatt' },
|
||||
]
|
||||
|
||||
const Footer = (): JSX.Element => {
|
||||
const Footer = () => {
|
||||
return (
|
||||
<footer>
|
||||
<div className="items-start max-w-6xl px-5 py-8 mx-auto lg:py-12 grid lg:px-4 grid-cols-1 lg:grid-cols-4 gap-x-12 gap-y-5">
|
||||
|
|
|
@ -21,7 +21,7 @@ const FUNFACTS_DATA = [
|
|||
},
|
||||
]
|
||||
|
||||
const FunFacts = (): JSX.Element => {
|
||||
const FunFacts = () => {
|
||||
const [counter, setCounter] = React.useState({
|
||||
startCounter: false,
|
||||
})
|
||||
|
|
|
@ -28,7 +28,7 @@ const useMobile = (cb: UseMobileCallback) => {
|
|||
}, [])
|
||||
}
|
||||
|
||||
const HeaderHome = (): JSX.Element => {
|
||||
const HeaderHome = () => {
|
||||
const [displayMobileMenu, setDisplayMobileMenu] = React.useState(false)
|
||||
|
||||
useMobile((e) => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export const Check = (): JSX.Element => {
|
||||
export const Check = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -14,7 +14,7 @@ export const Check = (): JSX.Element => {
|
|||
)
|
||||
}
|
||||
|
||||
export const Times = (): JSX.Element => {
|
||||
export const Times = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -30,7 +30,7 @@ export const Times = (): JSX.Element => {
|
|||
)
|
||||
}
|
||||
|
||||
export const Twitter = (): JSX.Element => {
|
||||
export const Twitter = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -42,7 +42,7 @@ export const Twitter = (): JSX.Element => {
|
|||
)
|
||||
}
|
||||
|
||||
export const Menu = (): JSX.Element => {
|
||||
export const Menu = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
|
|
@ -10,7 +10,7 @@ interface LayoutProps {
|
|||
const Layout: React.FC<LayoutProps> = ({
|
||||
children,
|
||||
pageTitle,
|
||||
}): JSX.Element => {
|
||||
}) => {
|
||||
return (
|
||||
<div>
|
||||
<Head>
|
||||
|
|
|
@ -8,7 +8,7 @@ interface LinkInternalProps {
|
|||
const Internal: React.FC<LinkInternalProps> = ({
|
||||
href,
|
||||
children,
|
||||
}): JSX.Element => {
|
||||
}) => {
|
||||
return (
|
||||
<Link href={href}>
|
||||
<a className="text-indigo-800 dark:text-indigo-400">{children}</a>
|
||||
|
@ -27,7 +27,7 @@ const External: React.FC<LinkExternalProps> = ({
|
|||
href,
|
||||
children,
|
||||
target = '_blank',
|
||||
}): JSX.Element => {
|
||||
}) => {
|
||||
return (
|
||||
<a
|
||||
className={classnames('text-indigo-800 dark:text-indigo-400', className)}
|
||||
|
|
|
@ -13,7 +13,7 @@ interface LinkProps {
|
|||
to: string
|
||||
}
|
||||
|
||||
const NavLinks = ({ onClick }: NavLinksProps): JSX.Element => {
|
||||
const NavLinks = ({ onClick }: NavLinksProps) => {
|
||||
const { pathname } = useRouter()
|
||||
const intl = useIntl()
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ const baseFeatures = [
|
|||
},
|
||||
]
|
||||
|
||||
const Pricing = (): JSX.Element => {
|
||||
const Pricing = () => {
|
||||
return (
|
||||
<section className="px-5 py-8 md:px-0 md:py-32" id="vad-kostar-det">
|
||||
<div className="max-w-2xl mx-auto">
|
||||
|
|
|
@ -28,7 +28,7 @@ const baseFeatures = [
|
|||
},
|
||||
]
|
||||
|
||||
const Pricing = (): JSX.Element => {
|
||||
const Pricing = () => {
|
||||
return (
|
||||
<section className="px-5 py-8 md:px-0 md:py-32" id="vad-kostar-det">
|
||||
<div className="max-w-2xl mx-auto">
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const Privacy = (): JSX.Element => {
|
||||
const Privacy = () => {
|
||||
return (
|
||||
<div>
|
||||
<div className="max-w-6xl mx-auto px-5 md:px-0 my-5 md:my-24 prose dark:prose-dark">
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const QA = (): JSX.Element => {
|
||||
const QA = () => {
|
||||
return (
|
||||
<div className="header">
|
||||
<div className="max-w-6xl px-5 mx-auto my-5 md:my-24 md:px-0 prose dark:prose-dark relative z-10">
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import React, { ReactNode } from "react"
|
||||
import React, { ReactNode } from 'react'
|
||||
|
||||
interface SectionTitleProps {
|
||||
text?: ReactNode
|
||||
title: ReactNode
|
||||
}
|
||||
|
||||
const SectionTitle = ({ text, title }: SectionTitleProps): JSX.Element => {
|
||||
const SectionTitle = ({ text, title }: SectionTitleProps) => {
|
||||
return (
|
||||
<div className="mb-16 text-center space-y-5">
|
||||
<h2 className="text-4xl md:text-5xl font-bold leading-tight text-gray-800 dark:text-white">
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
const Status = (): JSX.Element => {
|
||||
const Status = () => {
|
||||
return (
|
||||
<div className="max-w-6xl px-5 mx-auto my-5 md:my-24 md:px-0 prose dark:prose-dark">
|
||||
<h1>Status</h1>
|
||||
<h3>Funkar appen som den ska?</h3>
|
||||
<p>
|
||||
Nej, tyvärr inte.
|
||||
<br />🛑 iPhone
|
||||
<br />🛑 Android
|
||||
<br />
|
||||
🛑 iPhone
|
||||
<br />
|
||||
🛑 Android
|
||||
</p>
|
||||
<p>
|
||||
Vi har rapporter om att appen har problem för tillfället och har lokaliserat felet samt jobbar på en lösning.
|
||||
Vi har rapporter om att appen har problem för tillfället och har
|
||||
lokaliserat felet samt jobbar på en lösning.
|
||||
</p>
|
||||
<h3>Upptäckt några problem? Hjälp oss att fixa det</h3>
|
||||
<p>
|
||||
|
@ -35,7 +38,3 @@ const Status = (): JSX.Element => {
|
|||
}
|
||||
|
||||
export default Status
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ export const testimonials = [
|
|||
},
|
||||
]
|
||||
|
||||
const Testimonials = (): JSX.Element => {
|
||||
const Testimonials = () => {
|
||||
return (
|
||||
<Section padding="py-8 md:pt-32 md:pb-20">
|
||||
{testimonials.map((testimonial) => (
|
||||
|
@ -58,7 +58,9 @@ const Testimonials = (): JSX.Element => {
|
|||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="mt-2 text-gray-600 dark:text-gray-300">{testimonial.text}</p>
|
||||
<p className="mt-2 text-gray-600 dark:text-gray-300">
|
||||
{testimonial.text}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-col mt-4 text-pink-600">
|
||||
{testimonial.name}
|
||||
|
|
|
@ -16,76 +16,82 @@ interface TimelineProps {
|
|||
events: TimelineEvent[]
|
||||
}
|
||||
|
||||
const Timeline = ({ events }: TimelineProps): JSX.Element => {
|
||||
const Timeline = ({ events }: TimelineProps) => {
|
||||
return (
|
||||
<ul className="max-w-2xl border-gray-200 dark:border-gray-900 md:mx-auto md:border-l-2 space-y-4 md:space-y-12">
|
||||
{events.sort((a, b) => b.date.localeCompare(a.date)).map(({ date, media, importantDates, overview }) => (
|
||||
<li className="relative" key={date}>
|
||||
<div className="absolute top-0 items-center justify-center hidden w-10 h-10 text-white bg-indigo-400 border-4 border-white rounded-full md:flex -left-5 -top-2">
|
||||
<svg
|
||||
className="w-5 h-5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 6a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1zm1 3a1 1 0 100 2h6a1 1 0 100-2H7z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div className="hidden mb-4 ml-8 text-sm font-bold text-gray-700 dark:text-gray-400 capitalize md:block">
|
||||
{dateFormat(date)}
|
||||
</div>
|
||||
<div className="p-4 text-sm leading-relaxed bg-white dark:bg-gray-800 border-t-4 border-indigo-300 rounded-b shadow-md md:p-5 md:ml-8">
|
||||
<div className="block mb-4 text-lg font-bold text-gray-700 capitalize md:hidden">
|
||||
{events
|
||||
.sort((a, b) => b.date.localeCompare(a.date))
|
||||
.map(({ date, media, importantDates, overview }) => (
|
||||
<li className="relative" key={date}>
|
||||
<div className="absolute top-0 items-center justify-center hidden w-10 h-10 text-white bg-indigo-400 border-4 border-white rounded-full md:flex -left-5 -top-2">
|
||||
<svg
|
||||
className="w-5 h-5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 6a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1zm1 3a1 1 0 100 2h6a1 1 0 100-2H7z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div className="hidden mb-4 ml-8 text-sm font-bold text-gray-700 dark:text-gray-400 capitalize md:block">
|
||||
{dateFormat(date)}
|
||||
</div>
|
||||
{overview}
|
||||
{importantDates.length > 0 && (
|
||||
<div className="mt-4 text-sm">
|
||||
<div className="font-bold">Viktiga händelser</div>
|
||||
<ul className="pl-5 mt-2 list-disc space-y-2">
|
||||
{importantDates.sort((a, b) => b.date.localeCompare(a.date)).map((important, i) => (
|
||||
<li key={`${important.description}-${i}`}>
|
||||
{important.link ? (
|
||||
<Link.External href={important.link}>
|
||||
{important.description}
|
||||
</Link.External>
|
||||
) : (
|
||||
important.description
|
||||
)}
|
||||
<div className="text-xs text-gray-500">
|
||||
{important.date}
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="p-4 text-sm leading-relaxed bg-white border-t-4 border-indigo-300 rounded-b shadow-md dark:bg-gray-800 md:p-5 md:ml-8">
|
||||
<div className="block mb-4 text-lg font-bold text-gray-700 capitalize md:hidden">
|
||||
{dateFormat(date)}
|
||||
</div>
|
||||
)}
|
||||
{media.length > 0 && (
|
||||
<div className="mt-4 text-sm">
|
||||
<div className="font-bold">Media</div>
|
||||
<ul className="pl-5 mt-2 list-disc space-y-2">
|
||||
{media.sort((a, b) => b.date.localeCompare(a.date)).map((m) => (
|
||||
<li key={m.description}>
|
||||
{m.link ? (
|
||||
<Link.External href={m.link}>
|
||||
{m.description}
|
||||
</Link.External>
|
||||
) : (
|
||||
m.description
|
||||
)}
|
||||
<div className="text-xs text-gray-500">{m.date}</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
{overview}
|
||||
{importantDates.length > 0 && (
|
||||
<div className="mt-4 text-sm">
|
||||
<div className="font-bold">Viktiga händelser</div>
|
||||
<ul className="pl-5 mt-2 list-disc space-y-2">
|
||||
{importantDates
|
||||
.sort((a, b) => b.date.localeCompare(a.date))
|
||||
.map((important, i) => (
|
||||
<li key={`${important.description}-${i}`}>
|
||||
{important.link ? (
|
||||
<Link.External href={important.link}>
|
||||
{important.description}
|
||||
</Link.External>
|
||||
) : (
|
||||
important.description
|
||||
)}
|
||||
<div className="text-xs text-gray-500">
|
||||
{important.date}
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
{media.length > 0 && (
|
||||
<div className="mt-4 text-sm">
|
||||
<div className="font-bold">Media</div>
|
||||
<ul className="pl-5 mt-2 list-disc space-y-2">
|
||||
{media
|
||||
.sort((a, b) => b.date.localeCompare(a.date))
|
||||
.map((m) => (
|
||||
<li key={m.description}>
|
||||
{m.link ? (
|
||||
<Link.External href={m.link}>
|
||||
{m.description}
|
||||
</Link.External>
|
||||
) : (
|
||||
m.description
|
||||
)}
|
||||
<div className="text-xs text-gray-500">{m.date}</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import ButtonLink from './ButtonLink'
|
||||
import Timeline from './Timeline'
|
||||
|
||||
const TimelineLatest = (): JSX.Element => {
|
||||
|
||||
const TimelineLatest = () => {
|
||||
return (
|
||||
<section className="max-w-6xl px-5 py-8 mx-auto lg:px-0 lg:py-32 grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||
<div className="space-y-8">
|
||||
|
@ -29,9 +28,7 @@ const TimelineLatest = (): JSX.Element => {
|
|||
senast genom en polisanmälan. I ett försök att skapa transparens har
|
||||
vi sammanställt vad som hänt nedan.
|
||||
</p>
|
||||
<ButtonLink href="/aktuellt">
|
||||
Läs hela historien
|
||||
</ButtonLink>
|
||||
<ButtonLink href="/aktuellt">Läs hela historien</ButtonLink>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
export const H1: React.FC = ({ children }) => {
|
||||
type Heading = {
|
||||
children: string
|
||||
}
|
||||
|
||||
export const H1 = ({ children }: Heading) => {
|
||||
return (
|
||||
<h1 className="mb-5 text-4xl md:text-5xl font-semibold text-gray-800 dark:text-white">
|
||||
{children}
|
||||
|
@ -6,8 +10,10 @@ export const H1: React.FC = ({ children }) => {
|
|||
)
|
||||
}
|
||||
|
||||
export const H2: React.FC = ({ children }) => {
|
||||
export const H2 = ({ children }: Heading) => {
|
||||
return (
|
||||
<h2 className="mb-5 text-5xl font-semibold text-gray-800 dark:text-white">{children}</h2>
|
||||
<h2 className="mb-5 text-5xl font-semibold text-gray-800 dark:text-white">
|
||||
{children}
|
||||
</h2>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,60 +1,60 @@
|
|||
{
|
||||
"name": "skolplattformen-site",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/classnames": "^2.2.11",
|
||||
"classnames": "^2.3.1",
|
||||
"google-spreadsheet": "^3.1.15",
|
||||
"next": "^10.1.3",
|
||||
"next-images": "^1.4.0",
|
||||
"react": "^17.0.2",
|
||||
"react-countup": "^4.3.3",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-id-swiper": "^4.0.0",
|
||||
"react-intl": "^5.15.8",
|
||||
"react-scroll": "^1.8.2",
|
||||
"react-visibility-sensor": "^5.1.1",
|
||||
"sharp": "^0.28.1",
|
||||
"swiper": "6.1.1"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"postbuild": "next-sitemap",
|
||||
"start": "next start",
|
||||
"lint": "eslint './**/*.js'",
|
||||
"test": "is-ci test:ci test:watch",
|
||||
"test:ci": "jest",
|
||||
"test:watch": "jest --watch",
|
||||
"typecheck": "tsc --watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/typography": "^0.4.0",
|
||||
"@testing-library/jest-dom": "5.11.10",
|
||||
"@testing-library/react": "11.2.6",
|
||||
"@types/google-spreadsheet": "^3.1.5",
|
||||
"@types/gtag.js": "^0.0.4",
|
||||
"@types/jest": "^26.0.22",
|
||||
"@types/react": "^17.0.3",
|
||||
"@types/react-scroll": "^1.8.2",
|
||||
"@typescript-eslint/eslint-plugin": "^4.22.0",
|
||||
"@typescript-eslint/parser": "^4.22.0",
|
||||
"autoprefixer": "^10.2.5",
|
||||
"babel-eslint": "10.1.0",
|
||||
"eslint": "7.24.0",
|
||||
"eslint-config-prettier": "8.2.0",
|
||||
"eslint-plugin-prettier": "3.4.0",
|
||||
"eslint-plugin-react": "7.23.2",
|
||||
"identity-obj-proxy": "3.0.0",
|
||||
"is-ci-cli": "2.2.0",
|
||||
"jest": "26.6.3",
|
||||
"jest-watch-typeahead": "0.6.2",
|
||||
"next-sitemap": "^1.6.25",
|
||||
"postcss": "^8.2.10",
|
||||
"prettier": "2.2.1",
|
||||
"tailwindcss": "^2.1.1",
|
||||
"typescript": "^4.2.4"
|
||||
}
|
||||
}
|
||||
{
|
||||
"name": "skolplattformen-site",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/classnames": "^2.2.11",
|
||||
"classnames": "^2.3.1",
|
||||
"google-spreadsheet": "^3.1.15",
|
||||
"next": "^10.1.3",
|
||||
"next-images": "^1.4.0",
|
||||
"react": "^17.0.2",
|
||||
"react-countup": "^4.3.3",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-id-swiper": "^4.0.0",
|
||||
"react-intl": "^5.15.8",
|
||||
"react-scroll": "^1.8.2",
|
||||
"react-visibility-sensor": "^5.1.1",
|
||||
"sharp": "^0.28.1",
|
||||
"swiper": "6.1.1"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"postbuild": "next-sitemap",
|
||||
"start": "next start",
|
||||
"lint": "eslint './**/*.js'",
|
||||
"test": "is-ci test:ci test:watch",
|
||||
"test:ci": "jest",
|
||||
"test:watch": "jest --watch",
|
||||
"typecheck": "tsc --watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/typography": "^0.4.0",
|
||||
"@testing-library/jest-dom": "5.11.10",
|
||||
"@testing-library/react": "11.2.6",
|
||||
"@types/google-spreadsheet": "^3.1.5",
|
||||
"@types/gtag.js": "^0.0.4",
|
||||
"@types/jest": "^26.0.22",
|
||||
"@types/react": "^17.0.3",
|
||||
"@types/react-scroll": "^1.8.2",
|
||||
"@typescript-eslint/eslint-plugin": "^4.22.0",
|
||||
"@typescript-eslint/parser": "^4.22.0",
|
||||
"autoprefixer": "^10.2.5",
|
||||
"babel-eslint": "10.1.0",
|
||||
"eslint": "7.24.0",
|
||||
"eslint-config-prettier": "8.2.0",
|
||||
"eslint-plugin-prettier": "3.4.0",
|
||||
"eslint-plugin-react": "7.23.2",
|
||||
"identity-obj-proxy": "3.0.0",
|
||||
"is-ci-cli": "2.2.0",
|
||||
"jest": "26.6.3",
|
||||
"jest-watch-typeahead": "0.6.2",
|
||||
"next-sitemap": "^1.6.25",
|
||||
"postcss": "^8.2.10",
|
||||
"prettier": "2.2.1",
|
||||
"tailwindcss": "^2.1.1",
|
||||
"typescript": "^4.2.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import { pageview } from '../components/gtag'
|
|||
import messages, { Languages } from '../content/locale/'
|
||||
import { AppProps } from 'next/app'
|
||||
|
||||
export default function App({ Component, pageProps }: AppProps): JSX.Element {
|
||||
export default function App({ Component, pageProps }: AppProps) {
|
||||
const router = useRouter()
|
||||
const { locale = 'sv', defaultLocale } = router
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import { H1 } from '../components/Typography'
|
|||
import { GoogleSpreadsheet } from 'google-spreadsheet'
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
|
||||
interface Event {
|
||||
date: string
|
||||
description: string
|
||||
|
@ -38,18 +37,26 @@ const CurrentEventsPage: NextPage<TimelineProps> = ({ events }) => {
|
|||
let cachedEvents: TimelineEvent[]
|
||||
type VoidCallback = () => void
|
||||
|
||||
const timeout = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
|
||||
const runOrTimeout = (fun: VoidCallback, ms: number) => Promise.race([fun(), timeout(ms).then(() => Promise.reject(new Error('Timout')))])
|
||||
const timeout = (ms: number) =>
|
||||
new Promise((resolve) => setTimeout(resolve, ms))
|
||||
|
||||
export const getServerSideProps = async (): Promise<{props: TimelineProps}> => {
|
||||
const runOrTimeout = (fun: VoidCallback, ms: number) =>
|
||||
Promise.race([
|
||||
fun(),
|
||||
timeout(ms).then(() => Promise.reject(new Error('Timout'))),
|
||||
])
|
||||
|
||||
export const getServerSideProps = async (): Promise<{
|
||||
props: TimelineProps
|
||||
}> => {
|
||||
// This info has moved to Google Sheets instead
|
||||
// https://docs.google.com/spreadsheets/d/151I2PrWkhWKC8OW-GB_sbgtGDtf0Ta-WdVcUOo5sUDI/edit?usp=sharing
|
||||
const doc = new GoogleSpreadsheet(
|
||||
'151I2PrWkhWKC8OW-GB_sbgtGDtf0Ta-WdVcUOo5sUDI'
|
||||
)
|
||||
doc.useApiKey('AIzaSyB-ONvFoIE_LUu0sxWLaE8QfHfDSM5uBG8')
|
||||
|
||||
try {
|
||||
|
||||
await runOrTimeout(() => doc.loadInfo(), 1000)
|
||||
|
||||
const months = (
|
||||
|
@ -62,27 +69,24 @@ export const getServerSideProps = async (): Promise<{props: TimelineProps}> => {
|
|||
await doc.sheetsByTitle['importantDates'].getRows()
|
||||
).map(({ date, description, link = null }) => ({ date, description, link }))
|
||||
|
||||
const events: TimelineEvent[] = months.map(
|
||||
(month: { date: string; overview: string }) => ({
|
||||
...month,
|
||||
media: media.filter((media: { date: string }) =>
|
||||
media.date.startsWith(month.date.slice(0, 7))
|
||||
),
|
||||
importantDates: importantDates.filter((importantDate: { date: string }) =>
|
||||
importantDate.date.startsWith(month.date.slice(0, 7))
|
||||
),
|
||||
})
|
||||
)
|
||||
const events: TimelineEvent[] = months.map((month) => ({
|
||||
...month,
|
||||
media: media.filter(({ date }) =>
|
||||
date.startsWith(month.date.slice(0, 7))
|
||||
),
|
||||
importantDates: importantDates.filter(({ date }) =>
|
||||
date.startsWith(month.date.slice(0, 7))
|
||||
),
|
||||
}))
|
||||
|
||||
cachedEvents = events
|
||||
|
||||
return { props: { events } }
|
||||
} catch(err) {
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
if (!cachedEvents) throw err
|
||||
return { props: { events: cachedEvents }} // sometimes we might run into rate limits in google sheets. Just return the old value until we get back again
|
||||
return { props: { events: cachedEvents } } // sometimes we might run into rate limits in google sheets. Just return the old value until we get back again
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default CurrentEventsPage
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
|
@ -18,12 +14,6 @@
|
|||
"isolatedModules": true,
|
||||
"jsx": "preserve"
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"github": {
|
||||
"silent": true
|
||||
}
|
||||
"github": {
|
||||
"silent": true
|
||||
}
|
||||
}
|
||||
|
|
10692
packages/site/yarn.lock
10692
packages/site/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue