import type { LoaderArgs } from '@remix-run/node'; import { json, redirect } from '@remix-run/node'; import { createStyles, Title, SimpleGrid, Text, Button, ThemeIcon, Grid, Col, Image, Container, Group, Box } from '@mantine/core'; import { Server, Lock, Users, FileText, GitHub } from 'react-feather'; import { getUserId } from '~/session.server'; import { Link } from '@remix-run/react'; export async function loader({ request }: LoaderArgs) { const userId = await getUserId(request); if (userId) return redirect('/time-entries'); return json({}); } const features = [ { icon: FileText, title: 'Free and open source', description: 'All packages are published under GNU Public license v3, you can self host this app and use it for free forever' }, { icon: Server, title: 'Host anywhere', description: 'You can host this app on your own server or using any cloud provider, your choice' }, { icon: Lock, title: 'Privacy friendly, you own your data', description: 'No analytics or tracking scripts, no ads, no data sharing. You are in control of your data' }, { icon: Users, title: 'Flexible', description: 'Use it for yourself as single user or invite your team to collaborate, you can also use it as a public service as admin' } ]; const items = features.map((feature) => (
{feature.title} {feature.description}
)); const rem = (value: number) => `${value / 16}rem`; const useStyles = createStyles((theme) => ({ wrapper: { position: 'relative', boxSizing: 'border-box', backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[8] : theme.white }, inner: { position: 'relative', paddingTop: rem(32), paddingBottom: rem(32), [theme.fn.smallerThan('sm')]: { paddingBottom: rem(16), paddingTop: rem(16) } }, title: { fontSize: rem(62), fontWeight: 900, lineHeight: 1.1, margin: 0, padding: 0, color: theme.colorScheme === 'dark' ? theme.white : theme.black, [theme.fn.smallerThan('sm')]: { fontSize: rem(42), lineHeight: 1.2 } }, description: { marginTop: theme.spacing.xl, fontSize: rem(24), [theme.fn.smallerThan('sm')]: { fontSize: rem(18) } }, controls: { marginTop: `calc(${theme.spacing.xl}px * 2)`, [theme.fn.smallerThan('sm')]: { marginTop: theme.spacing.xl } }, control: { height: rem(54), paddingLeft: rem(38), paddingRight: rem(38), [theme.fn.smallerThan('sm')]: { height: rem(54), paddingLeft: rem(18), paddingRight: rem(18), flex: 1 } } })); export default function Index() { const { classes } = useStyles(); return ( <>

A{' '} self-hosted {' '} privacy friendly time tracking app

Time tracking app built with Remix, supports authentication, projects management, and monthly or custom reports

Your time, your data

Features {items} Light/dark theme Time entries (light theme) Time entries (dark theme) Time entries management Time entries editing Reports Reports Projects Projects management Projects management: new project ); }