Add teachers photos
This commit is contained in:
48
src/shadcn/ui/avatar.tsx
Normal file
48
src/shadcn/ui/avatar.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import * as React from "react"
|
||||
import * as AvatarPrimitive from "@radix-ui/react-avatar"
|
||||
|
||||
import { cn } from "@/shared/utils"
|
||||
|
||||
const Avatar = React.forwardRef<
|
||||
React.ElementRef<typeof AvatarPrimitive.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<AvatarPrimitive.Root
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
Avatar.displayName = AvatarPrimitive.Root.displayName
|
||||
|
||||
const AvatarImage = React.forwardRef<
|
||||
React.ElementRef<typeof AvatarPrimitive.Image>,
|
||||
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<AvatarPrimitive.Image
|
||||
ref={ref}
|
||||
className={cn("aspect-square h-full w-full", className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
AvatarImage.displayName = AvatarPrimitive.Image.displayName
|
||||
|
||||
const AvatarFallback = React.forwardRef<
|
||||
React.ElementRef<typeof AvatarPrimitive.Fallback>,
|
||||
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<AvatarPrimitive.Fallback
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex h-full w-full items-center justify-center rounded-full bg-muted",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
|
||||
|
||||
export { Avatar, AvatarImage, AvatarFallback }
|
||||
2
src/shared/data/teachers-photos/.gitignore
vendored
Normal file
2
src/shared/data/teachers-photos/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
sources/*
|
||||
sources/urls.txt
|
||||
47
src/shared/data/teachers-photos/scripts/crop.mjs
Normal file
47
src/shared/data/teachers-photos/scripts/crop.mjs
Normal file
@@ -0,0 +1,47 @@
|
||||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
import sharp from 'sharp'
|
||||
|
||||
import { dirname } from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url)) + '/'
|
||||
|
||||
async function cropImages(imagePaths) {
|
||||
try {
|
||||
await fs.mkdir(__dirname + '../cropped')
|
||||
} catch (err) {
|
||||
if (err.code !== 'EEXIST') {
|
||||
console.error('Failed to create directory:', err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for (const imagePath of imagePaths) {
|
||||
const imageFileName = path.basename(imagePath)
|
||||
const outputFileName = `${__dirname}../cropped/${imageFileName}`
|
||||
|
||||
try {
|
||||
const image = sharp(imagePath)
|
||||
const metadata = await image.metadata()
|
||||
|
||||
const minDimension = Math.min(metadata.width, metadata.height)
|
||||
|
||||
await image
|
||||
.extract({ left: 0, top: 0, width: minDimension, height: minDimension })
|
||||
.resize(96, 96, { fit: 'contain' })
|
||||
.toFile(outputFileName)
|
||||
|
||||
console.log(`Successfully cropped ${imageFileName}`)
|
||||
} catch (err) {
|
||||
console.error(`Failed to crop ${imageFileName}:`, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const files = await fs.readdir(__dirname + '../sources')
|
||||
const imagePaths = files
|
||||
.filter(f => f.toLowerCase().endsWith('.jpg') || f.toLowerCase().endsWith('.png'))
|
||||
.map(f => __dirname + '../sources/' + f)
|
||||
|
||||
await cropImages(imagePaths)
|
||||
28
src/shared/data/teachers-photos/scripts/download.zsh
Executable file
28
src/shared/data/teachers-photos/scripts/download.zsh
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
# Read each line from urls.txt
|
||||
while IFS= read -r url; do
|
||||
# Extract file name from URL
|
||||
filename=$(basename $url)
|
||||
|
||||
# Download the content to a temporary file
|
||||
temp_file=$(mktemp)
|
||||
curl -s -o $temp_file $url
|
||||
|
||||
# Check if download was successful
|
||||
if [[ $? -eq 0 ]]; then
|
||||
# Use 'file --mime-type' to determine the mime type of the file
|
||||
content_type=$(file --mime-type -b $temp_file)
|
||||
|
||||
# Check if the content type starts with 'image'
|
||||
if [[ $content_type == image/* ]]; then
|
||||
echo "$filename downloaded successfully."
|
||||
mv $temp_file $filename
|
||||
else
|
||||
echo "Skipping $filename (Content type is not image)."
|
||||
rm -f $temp_file
|
||||
fi
|
||||
else
|
||||
echo "Failed to download $filename."
|
||||
fi
|
||||
done < urls.txt
|
||||
16
src/shared/data/teachers-photos/scripts/rename-decode.mjs
Normal file
16
src/shared/data/teachers-photos/scripts/rename-decode.mjs
Normal file
@@ -0,0 +1,16 @@
|
||||
import fs from 'fs/promises'
|
||||
|
||||
import { dirname } from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url)) + '/'
|
||||
|
||||
const files = await fs.readdir(__dirname + '../sources')
|
||||
const images = files
|
||||
.filter(f => f.toLowerCase().endsWith('.jpg') || f.toLowerCase().endsWith('.png'))
|
||||
.filter(f => f.startsWith('%'))
|
||||
|
||||
for(const image of images) {
|
||||
console.log(image, '->', decodeURIComponent(image))
|
||||
await fs.rename(__dirname + '../sources/' + image, __dirname + '../sources/' + decodeURIComponent(image))
|
||||
}
|
||||
247
src/shared/data/teachers.ts
Normal file
247
src/shared/data/teachers.ts
Normal file
@@ -0,0 +1,247 @@
|
||||
// https://gist.github.com/VityaSchel/28f1a360ee7798511765910b39c6086c
|
||||
export const teachers = [
|
||||
{
|
||||
'name': 'Абалымова Людмила Павловна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/abalimova-l-.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Абрамова Светлана Геннадьевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/qwefdsfsd.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Алехин Иван Николаевич',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/alehin-i-n.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Амукова Светлана Николаевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/'
|
||||
},
|
||||
{
|
||||
'name': 'Андреева Елена Сергеевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/-i-n.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Андреевская Наталья Владимировна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2021/IMG_5419.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Андрющенко Анна Вячеславовна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/andriushenko.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Арефьев Андрей Андреевич',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/%20class='
|
||||
},
|
||||
{
|
||||
'name': 'Бондаренко Анастасия Вячеславовна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/9GLhbTgCmhk.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Горшенина Ольга Николаевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/new/gorwenina-o-n.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Дмитриева Наталья Владимировна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/new/dmitrieva-n-v.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Елисеева Эмиля Владиславовна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/9GLhbTgC.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Ермолаева Галина Владимировна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/new/ermolaeva-g-v.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Жабборова Светлана Сергеевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/new/tryaskina-s-s.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Жилина Елена Николаевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/jilina.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Иванова Мария Сергеевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/konovalova.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Карпеева Александра Сергеевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/2014-karpeeva-a-s.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Карпова Ирина Васильевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/new/karpova-i-v.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Козько Диана Игоревна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/kozko-d-i.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Корнилова Светлана Александровна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/new/kornilova-s-a.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Краюшкина Ольга Борисовна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/fsdadsd.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Крынкина Анна Андреевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/%D0%A7%D0%B0%D0%B4%D0%B5%D0%BD%D0%BA%D0%BE%D0%B2%D0%B0%20DSC06721.JPG'
|
||||
},
|
||||
{
|
||||
'name': 'Кукарская Людмила Петровна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/new/kukarskaya-l-p.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Кусаева Зарина Владимировна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2022/%D0%B0%D0%B2%D0%BF%D0%BA%D1%83%D0%BF%D1%8B%D0%BF.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Ларионова Софья Николаевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Лизунова Елена Владимировна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/lizunova.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Лобачева Милана Евгеньевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/new/lobacheva-m-e.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Логвинов Александр Владимирович',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/new/logvinov_a_v.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Малбасарова Галия Худанбаевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/2014-kuntaeva.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Матулина Татьяна Сергеевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/matulina.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Михалькова Ирина Евгеньевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/2019-mihalkova.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Назарова Елена Федоровна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/nazarova.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Негина Айгуль Зинуловна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/2014-aitasova-a-z.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Некрылова Татьяна Борисовна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/new/nekrylova-t-b.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Никифоров Михаил Михайлович',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/new/nikiforov-m-m.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Першина Елена Викторовна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/new/pershina-e-v.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Потяйкин Роман Владимирович',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Рзаева Алина Игоревна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/DSC06789.JPG'
|
||||
},
|
||||
{
|
||||
'name': 'Савич Мария Владимировна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/asdasad.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Самойлова Наталья Николаевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2022/samoylova.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Семенов Антон Сергеевич',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/antonov-a-s.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Сергеев Роман Алексеевич',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Сиднина Юлия Валерьевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/new/%D1%81%D0%B8%D0%B4%D0%BD%D0%B8%D0%BD%D0%B0.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Синекопова Лариса Владимировна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/sinekopova-l-v.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Сироткина Ольга Владимировна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/new/sirotkina-o-v.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Ситникова Людмила Геннадьевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/new/sitnikova-l-.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Славкина Татьяна Анатольевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/slavkina-t-a.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Сорокина Надежда Леонидовна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/new/sorokina-n.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Странник Дмитрий Христианович',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/stranik.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Тананыхина Надежда Воалимировна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/IMG-f8eeb02.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Терёхин Дмитрий Вячеславович',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/terexin.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Упанова Анастасия Владимировна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Утыбаева Светлана Михайловна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/2019-utibaeva-s-m.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Федотова Елена Дмитриевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/fedotova-e-.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Фомин Александр Васильевич',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/new/fomin-a-v.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Ходотова Евгения Андреевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/hodotova.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Черненкова Наталья Владимировна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/new/chernenkova-n-v.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Шамбер Лола Низамовна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/shamber-l-n.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Шомас Елена Александровна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/2014-shomas.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Шукова Марина Геннадьевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/emp/new/shykova.jpg'
|
||||
},
|
||||
{
|
||||
'name': 'Щербакова Надежда Юрьевна',
|
||||
'picture': 'https://ks.psuti.ru/images/stories/ks-news/2016/prepodavateli-foto/andreeva.jpg'
|
||||
}
|
||||
]
|
||||
@@ -1,9 +1,29 @@
|
||||
import type { Day as DayType } from '@/shared/model/day'
|
||||
import { Lesson } from '@/widgets/schedule/lesson'
|
||||
|
||||
export function Day({ day }: {
|
||||
day: DayType
|
||||
}) {
|
||||
const dayOfWeek = [
|
||||
'Понедельник',
|
||||
'Вторник',
|
||||
'Среда',
|
||||
'Четверг',
|
||||
'Пятница',
|
||||
'Суббота',
|
||||
'Воскресенье'
|
||||
][day.date.getDay()-1]
|
||||
|
||||
return (
|
||||
<p></p>
|
||||
<div className="flex flex-col gap-5">
|
||||
<h1 className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
|
||||
{dayOfWeek}
|
||||
</h1>
|
||||
<div className="flex flex-row gap-4">
|
||||
{day.lessons.map((lesson, i) => (
|
||||
<Lesson lesson={lesson} key={i} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -6,7 +6,7 @@ export function Schedule({ days }: {
|
||||
}) {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="flex flex-col p-16 gap-14">
|
||||
{days.map((day, i) => (
|
||||
<Day day={day} key={i} />
|
||||
))}
|
||||
|
||||
@@ -7,46 +7,49 @@ import {
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from '@/shadcn/ui/card'
|
||||
import { Input } from '@/shadcn/ui/input'
|
||||
import { Label } from '@/shadcn/ui/label'
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from '@/shadcn/ui/select'
|
||||
Avatar,
|
||||
AvatarFallback,
|
||||
AvatarImage,
|
||||
} from '@/shadcn/ui/avatar'
|
||||
import { teachers } from '@/shared/data/teachers'
|
||||
import { Lesson as LessonType } from '@/shared/model/lesson'
|
||||
|
||||
export function Lesson({ lesson }: {
|
||||
lesson: LessonType
|
||||
}) {
|
||||
const teacherObj = lesson.teacher ? teachers.find(t => t.name === lesson.teacher) : null
|
||||
|
||||
const getTeacherPhoto = (url?: string) => {
|
||||
if(url) {
|
||||
try {
|
||||
const filename = decodeURIComponent(new URL(url).pathname.split('/').pop()!)
|
||||
return `/teachers/${filename}`
|
||||
} catch(e) {
|
||||
console.error(e)
|
||||
return null
|
||||
}
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export function Lesson() {
|
||||
return (
|
||||
<Card className="w-[350px]">
|
||||
<CardHeader>
|
||||
<CardTitle>Create project</CardTitle>
|
||||
<CardDescription>Deploy your new project in one-click.</CardDescription>
|
||||
</CardHeader>
|
||||
<Card className="w-[350px]">
|
||||
<div>
|
||||
<Avatar>
|
||||
<AvatarImage src={getTeacherPhoto(teacherObj?.picture)} alt="@shadcn" />
|
||||
<AvatarFallback>CN</AvatarFallback>
|
||||
</Avatar>
|
||||
<Avatar></Avatar>
|
||||
<CardHeader>
|
||||
<CardTitle>{lesson.subject}</CardTitle>
|
||||
<CardDescription>{lesson.teacher}</CardDescription>
|
||||
<CardDescription>{lesson.place?.classroom}</CardDescription>
|
||||
</CardHeader>
|
||||
</div>
|
||||
<CardContent>
|
||||
<form>
|
||||
<div className="grid w-full items-center gap-4">
|
||||
<div className="flex flex-col space-y-1.5">
|
||||
<Label htmlFor="name">Name</Label>
|
||||
<Input id="name" placeholder="Name of your project" />
|
||||
</div>
|
||||
<div className="flex flex-col space-y-1.5">
|
||||
<Label htmlFor="framework">Framework</Label>
|
||||
<Select>
|
||||
<SelectTrigger id="framework">
|
||||
<SelectValue placeholder="Select" />
|
||||
</SelectTrigger>
|
||||
<SelectContent position="popper">
|
||||
<SelectItem value="next">Next.js</SelectItem>
|
||||
<SelectItem value="sveltekit">SvelteKit</SelectItem>
|
||||
<SelectItem value="astro">Astro</SelectItem>
|
||||
<SelectItem value="nuxt">Nuxt.js</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</CardContent>
|
||||
<CardFooter className="flex justify-between">
|
||||
<Button variant="outline">Cancel</Button>
|
||||
|
||||
Reference in New Issue
Block a user