Skip to content

Commit d957b3f

Browse files
committed
UPDATE: readme
ADD: concept of generating csv file
1 parent 5a0e6df commit d957b3f

File tree

8 files changed

+163
-96
lines changed

8 files changed

+163
-96
lines changed

QUICK_START.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
# Quick Start
22

33
1. Download [NodeJS](https://nodejs.org/en/download/)
4-
2. Start up main app:
4+
2. Install bun (optional)
5+
6+
```bash
7+
npm i -g bun
8+
```
9+
10+
3. Start up main app:
511

612
```bash
713
cd main-app
814
npm install
915
npm run dev
1016
```
1117

12-
3. Start up react-redirect
18+
4. Start up react-redirect
1319

1420
```bash
1521
cd redirect-app

README.md

+18-21
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,31 @@
1-
# ShortyWebClient
2-
3-
[![CodeFactor](https://www.codefactor.io/repository/github/bagger-steam/shortyreactclient/badge)](https://www.codefactor.io/repository/github/bagger-steam/shortyreactclient)
4-
![CI](https://github.com/Bagger-sTeam/ShortyReactClient/workflows/CI/badge.svg?)
1+
<h1 align="center">Shorty</h1>
2+
3+
<p align="center">
4+
<img alt="" src="https://img.shields.io/badge/Next-black?style=for-the-badge&logo=next.js&logoColor=white" />
5+
<img alt="" src="https://img.shields.io/badge/react-%2320232a.svg?style=for-the-badge&logo=react&logoColor=%2361DAFB" />
6+
<img alt="" src="https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white" />
7+
<img alt="" src="https://img.shields.io/badge/tailwindcss-%2338B2AC.svg?style=for-the-badge&logo=tailwind-css&logoColor=white" />
8+
<img alt="" src="https://img.shields.io/badge/Bun-%23000000.svg?style=for-the-badge&logo=bun&logoColor=white" />
9+
<img alt="" src="https://img.shields.io/badge/-React%20Query-FF4154?style=for-the-badge&logo=react%20query&logoColor=white" />
10+
<img alt="" src="https://img.shields.io/badge/ESLint-4B3263?style=for-the-badge&logo=eslint&logoColor=white" />
11+
<img alt="" src="https://img.shields.io/badge/docker-%230db7ed.svg?style=for-the-badge&logo=docker&logoColor=white" />
12+
</p>
513

614
## Overview
715

8-
This is React client application for **[Shorty Api](https://github.com/Bagger-sTeam/ShortyRestApi)**
9-
10-
## 💻 Tech Stack
16+
Shorty is a service for URL shortening, analytics, and short link management. With Shorty, you can easily create short links, track their statistics, and manage them all in one place.
1117

12-
- [TypeScript](https://www.typescriptlang.org/)
13-
- [React](https://reactjs.org/)
14-
- [NextJS](https://nextjs.org/)
15-
- [Next Auth](https://next-auth.js.org/)
16-
- [Tailwind CSS](https://tailwindcss.com/)
17-
- [Docker](https://www.docker.com/)
18+
This repository is part of the overall Shorty project. To find out about the backend components of the site, look at **[Shorty Server](https://github.com/Bagger-sTeam/ShortyRestApi)**.
1819

19-
## 💾 Installation
20+
## Installation
2021

21-
1. [Quick install](QUICK_START.md)
22+
1. [Quick start](QUICK_START.md)
2223
2. Install by **docker-compose**
2324

2425
```bash
25-
docker-compose up
26+
docker compose up
2627
```
2728

28-
## 👇 Helpful resources
29-
30-
- [ShortyApi](https://github.com/Bagger-sTeam/ShortyRestApi)
31-
32-
## 🚑 Support
29+
## Support
3330

3431
Please click the `star` button, if this tool was helpful to you.

RESOURCES.md

-3
This file was deleted.

main-app/src/features/create-link-form/create-form-context.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export const currentDomain = signal<DomainType>({
1212
export const subdomainStub = signal<SubdomainType>({
1313
value: 'Unselected',
1414
uid: uuidv4(),
15-
domainUid: ''
15+
domainUid: '',
1616
})
1717

1818
export const currentSubdomain = signal<SubdomainType>(subdomainStub.value)

main-app/src/features/date-picker-with-range/date-picker-with-range.tsx

-61
This file was deleted.

main-app/src/features/date-picker-with-range/index.ts

-3
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import { CalendarDaysIcon } from '@heroicons/react/24/outline'
2+
import { zodResolver } from '@hookform/resolvers/zod'
3+
import { addDays, format } from 'date-fns'
4+
import { useForm } from 'react-hook-form'
5+
import { z } from 'zod'
6+
7+
import cn from '@/shared/lib/tailwind-merge'
8+
import { Button } from '@/shared/ui/button'
9+
import { Calendar } from '@/shared/ui/calendar'
10+
import { Form, FormControl, FormField, FormItem } from '@/shared/ui/form'
11+
import { Popover, PopoverContent, PopoverTrigger } from '@/shared/ui/popover'
12+
import { useToast } from '@/shared/ui/use-toast'
13+
14+
const testData = [
15+
{
16+
redirectDate: new Date(),
17+
os: 'Windows',
18+
device: 'Mobile',
19+
isUnique: true,
20+
},
21+
{
22+
redirectDate: new Date(),
23+
os: 'Windows',
24+
device: 'Desktop',
25+
isUnique: false,
26+
},
27+
]
28+
29+
const analyticsFormScheme = z.object({
30+
date: z.object({
31+
from: z.date(),
32+
to: z.date(),
33+
}),
34+
})
35+
36+
export default function CsvGenerateForm() {
37+
const { toast } = useToast()
38+
const form = useForm<z.infer<typeof analyticsFormScheme>>({
39+
resolver: zodResolver(analyticsFormScheme),
40+
defaultValues: {
41+
date: {
42+
from: addDays(new Date(), -20),
43+
to: new Date(),
44+
},
45+
},
46+
})
47+
48+
const onSubmit = (values: z.infer<typeof analyticsFormScheme>) => {
49+
console.log(values)
50+
toast({
51+
title: 'Values',
52+
description: `from: ${values.date.from}\nto: ${values.date.to}`,
53+
})
54+
window.open(generateCsv())
55+
}
56+
57+
// eslint-disable-next-line unicorn/consistent-function-scoping
58+
const generateCsv = (): string => {
59+
const headers = ['Index', 'RedirectDate', 'OS', 'Device', 'Unique']
60+
let csvContent = 'data:text/csv;charset=utf-8,' + headers.join(';') + '\n'
61+
62+
testData.forEach((item, index) => {
63+
const row = [
64+
index + 1,
65+
item.redirectDate.toISOString(), // Convert date to ISO string format
66+
item.os,
67+
item.device,
68+
item.isUnique,
69+
].join(';')
70+
csvContent += row + '\n'
71+
})
72+
73+
console.log(csvContent)
74+
return encodeURI(csvContent)
75+
}
76+
77+
return (
78+
<Form {...form}>
79+
<form onSubmit={form.handleSubmit(onSubmit)} className="flex gap-3">
80+
<FormField
81+
control={form.control}
82+
name="date"
83+
render={({ field }) => (
84+
<FormItem>
85+
<FormControl>
86+
<div className="grid gap-2">
87+
<Popover>
88+
<PopoverTrigger asChild>
89+
<Button
90+
id="date"
91+
variant="outline"
92+
className={cn(
93+
'w-[300px] justify-start text-left font-normal',
94+
!field.value && 'text-muted-foreground'
95+
)}
96+
>
97+
<CalendarDaysIcon className="mr-2 size-4" />
98+
{field.value?.from ? (
99+
field.value.to ? (
100+
<>
101+
{format(field.value.from, 'LLL dd, y')} -{' '}
102+
{format(field.value.to, 'LLL dd, y')}
103+
</>
104+
) : (
105+
format(field.value.from, 'LLL dd, y')
106+
)
107+
) : (
108+
<span>Pick a date</span>
109+
)}
110+
</Button>
111+
</PopoverTrigger>
112+
<PopoverContent className="w-auto p-0" align="start">
113+
<Calendar
114+
initialFocus
115+
mode="range"
116+
fromMonth={addDays(new Date(), -80)}
117+
toDate={new Date()}
118+
defaultMonth={field.value.from}
119+
selected={field.value}
120+
onSelect={field.onChange}
121+
numberOfMonths={2}
122+
/>
123+
</PopoverContent>
124+
</Popover>
125+
</div>
126+
</FormControl>
127+
</FormItem>
128+
)}
129+
/>
130+
<Button type="submit">Download</Button>
131+
</form>
132+
</Form>
133+
)
134+
}

main-app/src/widgets/dashboard/dashboard.tsx

+2-5
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ import {
1515
useGetAnalyticsByLink,
1616
} from '@/entities/analytics'
1717
import { useGetCurrentRecord } from '@/entities/record'
18-
import DatePickerWithRange from '@/features/date-picker-with-range'
1918
import { Button } from '@/shared/ui/button'
2019
import { Tabs, TabsList, TabsTrigger } from '@/shared/ui/tabs'
2120
import { useToast } from '@/shared/ui/use-toast'
2221

22+
import CsvGenerateForm from './csv-generate-form'
2323
import DashboardCard from './dashboard-card'
2424
import DeviceCard from './device-card'
2525
import ViewsCard from './views-card'
@@ -64,10 +64,7 @@ export default function Dashboard() {
6464
Reset
6565
</Button>
6666
</div>
67-
<div className="flex gap-3">
68-
<DatePickerWithRange />
69-
<Button>Download</Button>
70-
</div>
67+
<CsvGenerateForm />
7168
</div>
7269
<Tabs
7370
value={period}

0 commit comments

Comments
 (0)