Compare commits
5 Commits
Author | SHA1 | Date |
---|---|---|
Tocho Tochev | 0aa45b4514 | |
Vencislav Atanasov | cbd213da21 | |
DanieII | 0f2e1373c2 | |
DanieII | d668093240 | |
Iliyan Georgiev | 9b090d212a |
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"trailingComma": "es5",
|
||||
"semi": true,
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true,
|
||||
"jsxSingleQuote": true,
|
||||
"plugins": [
|
||||
"prettier-plugin-tailwindcss"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
|
@ -1,3 +1,5 @@
|
|||
# OpenFest Website
|
||||
|
||||
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
||||
|
||||
## Getting Started
|
||||
|
@ -34,3 +36,7 @@ You can check out [the Next.js GitHub repository](https://github.com/vercel/next
|
|||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
||||
|
||||
## License
|
||||
|
||||
GPL v2 or later, see LICENSE.txt
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import "server-only";
|
||||
import type { Locale } from "./i18n-config";
|
||||
import 'server-only';
|
||||
import type { Locale } from './i18n-config';
|
||||
|
||||
// We enumerate all dictionaries here for better linting and typescript support
|
||||
// We also get the default import for cleaner types
|
||||
const dictionaries = {
|
||||
en: () => import("./dictionaries/en.json").then((module) => module.default),
|
||||
bg: () => import("./dictionaries/bg.json").then((module) => module.default),
|
||||
en: () => import('./dictionaries/en.json').then((module) => module.default),
|
||||
bg: () => import('./dictionaries/bg.json').then((module) => module.default),
|
||||
};
|
||||
|
||||
export const getDictionary = async (locale: Locale) =>
|
||||
dictionaries[locale]?.() ?? dictionaries.en();
|
||||
dictionaries[locale]?.() ?? dictionaries.en();
|
||||
|
|
|
@ -1,5 +1,46 @@
|
|||
{
|
||||
"nav": {
|
||||
"home": "Начало",
|
||||
"about": "За нас",
|
||||
"partners": "Партньори",
|
||||
"archive": "Архив",
|
||||
"contact": "Контакти"
|
||||
},
|
||||
"main": {
|
||||
"hello": "Добре дошли"
|
||||
"date": "2 - 3 ноември 2024",
|
||||
"titleLocation": "София Тех Парк",
|
||||
"countdownTimer": {
|
||||
"title": "До OpenFest остават",
|
||||
"days": "Дни",
|
||||
"hours": "Часа",
|
||||
"minutes": "Минути"
|
||||
},
|
||||
"description": {
|
||||
"title": "Какво е OpenFest?",
|
||||
"text": "OpenFest е най-голямата българска конференция, посветена на свободната култура, свободното споделяне на знание, свободния и отворен софтуер. Събитието се организира от доброволци и е безплатно за посещение. OpenFest се провежда годишно в София, България."
|
||||
},
|
||||
"cfp": {
|
||||
"title": "Как можете да участвате в OpenFest 2024?",
|
||||
"lecture": "Участвайте с лекция, работилница или щанд",
|
||||
"volunteers": "Присъединете се като доброволец",
|
||||
"partners": "Подкрепете събитието като партньор"
|
||||
},
|
||||
"news": {
|
||||
"title": "Новини",
|
||||
"cardButton": "Прочети",
|
||||
"button": "Виж всички"
|
||||
},
|
||||
"partners": {
|
||||
"sponsors": "Sponsors",
|
||||
"media": "Media partners"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"description": "OpenFest е събитие, посветена на свободната култура, свободния софтуер и софтуера с отворен код, свободното споделяне на знания.",
|
||||
"eventDate": "2-ри и 3-ти ноември 2024г.",
|
||||
"eventLocation": "София Тех Парк",
|
||||
"contactTeam": "Свържете се с екипа",
|
||||
"contactDirections": "Ако имате въпроси, предложения или желаете да се включите в OpenFest 2024, пишете ни:",
|
||||
"copyright": "Някои права запазени."
|
||||
}
|
||||
}
|
|
@ -1,5 +1,46 @@
|
|||
{
|
||||
"nav": {
|
||||
"home": "Home",
|
||||
"about": "About us",
|
||||
"partners": "Partners",
|
||||
"archive": "Archive",
|
||||
"contact": "Contact"
|
||||
},
|
||||
"main": {
|
||||
"hello": "Welcome"
|
||||
"date": "2 - 3 november 2024",
|
||||
"titleLocation": "Sofia Tech Park",
|
||||
"countdownTimer": {
|
||||
"title": "OpenFest starts in",
|
||||
"days": "Days",
|
||||
"hours": "Hours",
|
||||
"minutes": "Minutes"
|
||||
},
|
||||
"description": {
|
||||
"title": "What is OpenFest...",
|
||||
"text": "OpenFest is the biggest Bulgarian conference dedicated to the free culture, free knowledge sharing, free and open-source software. The event is organized by volunteers and is free to attend. OpenFest is held annually in Sofia, Bulgaria."
|
||||
},
|
||||
"cfp": {
|
||||
"title": "How to participate in OpenFest 2024?",
|
||||
"lecture": "Take part with a lecture, a workshop or a booth",
|
||||
"volunteers": "Join us as a volunteer",
|
||||
"partners": "Support the event as a partner"
|
||||
},
|
||||
"news": {
|
||||
"title": "News",
|
||||
"cardButton": "Read",
|
||||
"button": "See all"
|
||||
},
|
||||
"partners": {
|
||||
"sponsors": "Sponsors",
|
||||
"media": "Media partners"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"description": "OpenFest is a event dedicated to free culture, free and open-source software, and free sharing of knowledge.",
|
||||
"eventDate": "2-3 November 2024",
|
||||
"eventLocation": "Sofia Tech Park",
|
||||
"contactTeam": "Connect with the team",
|
||||
"contactDirections": "If you have any questions and suggestions or if you would like to participate in OpenFest 2024, get in touch with us:",
|
||||
"copyright": "Some rights reserved."
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
export const i18n = {
|
||||
defaultLocale: "en",
|
||||
locales: ["en", "bg"],
|
||||
locales: ['bg', 'en'],
|
||||
defaultLocale: 'bg',
|
||||
localeDetection: true,
|
||||
} as const;
|
||||
|
||||
export type Locale = (typeof i18n)["locales"][number];
|
||||
export type Locale = (typeof i18n)['locales'][number];
|
||||
|
|
|
@ -12,8 +12,8 @@ const nextConfig = {
|
|||
destination: '/news/1',
|
||||
permanent: true,
|
||||
},
|
||||
]
|
||||
];
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default nextConfig
|
||||
export default nextConfig;
|
||||
|
|
27
package.json
|
@ -1,18 +1,22 @@
|
|||
{
|
||||
"name": "openfest",
|
||||
"version": "0.1.0",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint"
|
||||
"lint": "next lint",
|
||||
"format": "prettier --check --ignore-path .gitignore .",
|
||||
"format:fix": "prettier --write --ignore-path .gitignore ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@formatjs/intl-localematcher": "^0.5.4",
|
||||
"@headlessui/react": "^2.1.5",
|
||||
"gray-matter": "^4.0.3",
|
||||
"negotiator": "^0.6.3",
|
||||
"next": "14.2.3",
|
||||
"next": "^14.2.8",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"remark": "^15.0.1",
|
||||
|
@ -21,14 +25,19 @@
|
|||
"strip-markdown": "^6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@heroicons/react": "^2.1.5",
|
||||
"@types/negotiator": "^0.6.3",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^18",
|
||||
"@types/node": "^22.5.4",
|
||||
"@types/react": "^18.3.5",
|
||||
"@types/react-dom": "^18",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "14.2.3",
|
||||
"postcss": "^8",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"typescript": "^5"
|
||||
"autoprefixer": "^10.4.20",
|
||||
"eslint": "^9.10.0",
|
||||
"eslint-config-next": "^14.2.8",
|
||||
"install": "^0.13.0",
|
||||
"npm": "^10.8.3",
|
||||
"postcss": "^8.4.45",
|
||||
"prettier-plugin-tailwindcss": "^0.6.6",
|
||||
"tailwindcss": "^3.4.10",
|
||||
"typescript": "^5.5.4"
|
||||
}
|
||||
}
|
||||
|
|
After Width: | Height: | Size: 951 KiB |
After Width: | Height: | Size: 1001 KiB |
After Width: | Height: | Size: 1.6 MiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 8.6 KiB |
|
@ -1,8 +0,0 @@
|
|||
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css');
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
.container {
|
||||
@apply mx-auto px-6;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
import { i18n } from '../../../i18n-config';
|
||||
|
||||
import NavBar from '../../components/NavBar';
|
||||
import Footer from '@/components/Footer';
|
||||
|
||||
import '@/styles/globals.css';
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return i18n.locales.map((locale) => ({ lang: locale }));
|
||||
}
|
||||
|
||||
export const metadata = {
|
||||
title: 'OpenFest 2024',
|
||||
description: 'Да се видим на OpenFest 2024!',
|
||||
};
|
||||
|
||||
export default function RootLayout({ children, params }) {
|
||||
return (
|
||||
<html lang={params.lang}>
|
||||
<body
|
||||
className={`flex min-h-screen flex-col font-openSans text-white md:text-lg lg:text-xl`}
|
||||
>
|
||||
<header>
|
||||
<NavBar lang={params.lang} />
|
||||
</header>
|
||||
<main>{children}</main>
|
||||
<Footer lang={params.lang} />
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
import type { Metadata } from 'next'
|
||||
import { Inter } from 'next/font/google'
|
||||
import './globals.css'
|
||||
import { i18n, type Locale } from '../../../i18n-config'
|
||||
import NavBar from '../../components/NavBar'
|
||||
import Footer from '../../components/Footer'
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return i18n.locales.map((locale) => ({ lang: locale }))
|
||||
}
|
||||
|
||||
const inter = Inter({ subsets: ['latin'] })
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Create Next App',
|
||||
description: 'Generated by create next app',
|
||||
}
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
params,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode
|
||||
params: { lang: Locale }
|
||||
}>) {
|
||||
return (
|
||||
<html lang={params.lang}>
|
||||
<body
|
||||
className={`${inter.className}, flex flex-col text-white md:text-lg lg:text-xl min-h-screen`}
|
||||
>
|
||||
<NavBar lang={params.lang} />
|
||||
{children}
|
||||
<Footer />
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
// import { getSortedPostsData } from '../../lib/posts';
|
||||
// import { getDictionary } from '../../../dictionaries';
|
||||
|
||||
export default async function PageNovini({ params }) {
|
||||
const { lang } = params;
|
||||
// const dictionary = await getDictionary(lang);
|
||||
// const { posts } = await getSortedPostsData(lang);
|
||||
|
||||
return (
|
||||
<>
|
||||
<main>
|
||||
<div className='container flex flex-col py-8 lg:py-16 gap-8 lg:gap-16 text-black'>
|
||||
<div className='flex flex-col'>
|
||||
<h2 className='text-xl lg:text-3xl font-extrabold text-center mb-6 lg:mb-10'>
|
||||
news
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
import CountDownTimer from '@/components/CountDownTimer';
|
||||
import NewsFeed from '@/components/NewsFeed';
|
||||
import Partners from '@/components/Partners';
|
||||
import Image from 'next/image';
|
||||
import { getDictionary } from '@/dictionaries';
|
||||
|
||||
export default async function Home({ params }) {
|
||||
const { lang } = params;
|
||||
const dictionary = await getDictionary(lang);
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className='h-[65vh] bg-home-bg bg-cover bg-bottom sm:h-[75vh]'>
|
||||
<div className='container flex h-full flex-col justify-center gap-10 text-black sm:gap-16'>
|
||||
<div className='text-center'>
|
||||
<p className='font-semibold uppercase tracking-[0.2em] text-white sm:text-xl'>
|
||||
{dictionary.main.date}
|
||||
</p>
|
||||
<h1 className='text-6xl font-bold text-white sm:text-7xl'>
|
||||
OpenFest <br /> 2024
|
||||
</h1>
|
||||
</div>
|
||||
<div className='text-center'>
|
||||
<p className='pb-2 text-2xl font-semibold text-white sm:pb-4 sm:text-5xl'>
|
||||
“Let’s share the freedom!”
|
||||
</p>
|
||||
<p className='text-xl text-white sm:text-3xl'>
|
||||
{dictionary.main.titleLocation}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<CountDownTimer props={dictionary.main.countdownTimer} />
|
||||
<section className='bg-blue-8'>
|
||||
<div className='container flex flex-col gap-4 sm:gap-8'>
|
||||
<h2 className='text-center text-2xl text-blue-2 sm:text-4xl'>
|
||||
{dictionary.main.description.title}
|
||||
</h2>
|
||||
<div className='flex flex-col gap-6 sm:flex-row'>
|
||||
<div className='flex-1'>
|
||||
<p> {dictionary.main.description.text}</p>
|
||||
</div>
|
||||
<div className='flex-1'>
|
||||
<Image
|
||||
src='/images/openfest-2.webp'
|
||||
width='620'
|
||||
height='380'
|
||||
></Image>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<div className='container'>
|
||||
<h2 className='pb-4 text-center text-2xl text-blue-2 sm:pb-8 sm:text-4xl'>
|
||||
{dictionary.main.cfp.title}
|
||||
</h2>
|
||||
<div className='flex flex-col gap-4 sm:flex-row sm:gap-8'>
|
||||
<div className='flex basis-1/3 flex-col items-center justify-center gap-3 rounded-xl bg-blue-2 p-6 sm:gap-6'>
|
||||
<div className='flex h-20 w-20 items-center justify-center rounded-full bg-blue-8 text-4xl text-blue-2 shadow-md shadow-black sm:h-24 sm:w-24 sm:text-5xl'>
|
||||
<i className='fa-solid fa-lightbulb'></i>
|
||||
</div>
|
||||
<p className='text-center text-white'>
|
||||
{dictionary.main.cfp.lecture}
|
||||
</p>
|
||||
</div>
|
||||
<div className='flex basis-1/3 flex-col items-center justify-center gap-3 rounded-xl bg-blue-2 p-6 sm:gap-6'>
|
||||
<div className='flex h-20 w-20 items-center justify-center rounded-full bg-blue-8 text-4xl text-blue-2 shadow-md shadow-black sm:h-24 sm:w-24 sm:text-5xl'>
|
||||
<i className='fa-solid fa-helmet-safety'></i>
|
||||
</div>
|
||||
<p className='text-center text-white'>
|
||||
{dictionary.main.cfp.volunteers}
|
||||
</p>
|
||||
</div>
|
||||
<div className='flex basis-1/3 flex-col items-center justify-center gap-3 rounded-xl bg-blue-2 p-6 sm:gap-6'>
|
||||
<div className='flex h-20 w-20 items-center justify-center rounded-full bg-blue-8 text-4xl text-blue-2 shadow-md shadow-black sm:h-24 sm:w-24 sm:text-5xl'>
|
||||
<i className='fa-solid fa-handshake-angle'></i>
|
||||
</div>
|
||||
<p className='text-center text-white'>
|
||||
{dictionary.main.cfp.partners}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<NewsFeed lang={lang} />
|
||||
<Partners lang={lang} />
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
import Header from '../../components/Header'
|
||||
import Info from '../../components/Info'
|
||||
import JoinUs from '../../components/JoinUs'
|
||||
import Social from '../../components/Social'
|
||||
import News from '../../components/News'
|
||||
import { getSortedPostsData } from '../../lib/posts'
|
||||
import { getDictionary } from '../../../dictionaries'
|
||||
import { Locale } from '../../../i18n-config'
|
||||
|
||||
export default async function Home({
|
||||
params: { lang },
|
||||
}: {
|
||||
params: { lang: Locale }
|
||||
}) {
|
||||
const dictionary = await getDictionary(lang)
|
||||
const { posts } = await getSortedPostsData(lang)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main>
|
||||
<Info />
|
||||
<JoinUs />
|
||||
<div className='container flex flex-col py-8 lg:py-16 gap-8 lg:gap-16 text-black'>
|
||||
<div className='flex flex-col'>
|
||||
<h2 className='text-xl lg:text-3xl font-extrabold text-center mb-6 lg:mb-10'>
|
||||
Новини
|
||||
</h2>
|
||||
<News posts={posts} />
|
||||
</div>
|
||||
</div>
|
||||
<Social />
|
||||
</main>
|
||||
</>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
'use client';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
|
||||
const CountDownTimer = ({ props }) => {
|
||||
const [days, setDays] = useState(0);
|
||||
const [hours, setHours] = useState(0);
|
||||
const [minutes, setMinutes] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const targetDate = new Date('2024-11-02T09:30:00+03:00');
|
||||
const countDownIntervalTime = 1000;
|
||||
|
||||
const updateCountDown = () => {
|
||||
const now = new Date();
|
||||
|
||||
const diff = targetDate.getTime() - now.getTime();
|
||||
|
||||
const d = Math.floor(diff / (1000 * 60 * 60 * 24));
|
||||
setDays(d);
|
||||
|
||||
const h = Math.floor((diff / (1000 * 60 * 60)) % 24);
|
||||
setHours(h);
|
||||
|
||||
const m = Math.floor((diff / (1000 * 60)) % 60);
|
||||
setMinutes(m);
|
||||
};
|
||||
|
||||
// Set time
|
||||
updateCountDown();
|
||||
|
||||
// Set interval
|
||||
const interval = setInterval(updateCountDown, countDownIntervalTime);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<section>
|
||||
<div className='container flex flex-col gap-4 sm:gap-8'>
|
||||
<h2 className='text-center text-2xl text-blue-2 sm:text-start sm:text-4xl'>
|
||||
{props.title}
|
||||
</h2>
|
||||
<div className='flex flex-col items-center justify-evenly gap-8 lg:flex-row'>
|
||||
<div className='relative h-48 w-48 lg:h-64 lg:w-64'>
|
||||
<div className='absolute inset-0 rotate-[-45deg] overflow-hidden rounded-full bg-[#A9CDF7]'>
|
||||
<div className='absolute left-0 top-0 h-full w-1/2'></div>
|
||||
<div className='absolute left-0 top-0 h-full w-1/2 bg-[#C8E0FC]'></div>
|
||||
</div>
|
||||
<div className='absolute inset-0 flex items-center justify-center'>
|
||||
<span className='text-center font-bold'>
|
||||
<p className='pb-1 pt-2 text-6xl text-white lg:pb-3 lg:pt-4 lg:text-8xl'>
|
||||
{days}
|
||||
</p>
|
||||
<p className='text-2xl font-light text-white lg:text-5xl'>
|
||||
{props.days}
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className='relative h-48 w-48 lg:h-64 lg:w-64'>
|
||||
<div className='absolute inset-0 rotate-[-45deg] overflow-hidden rounded-full bg-[#A9CDF7]'>
|
||||
<div className='absolute left-0 top-0 h-full w-full'></div>
|
||||
</div>
|
||||
<div className='absolute inset-0 flex items-center justify-center'>
|
||||
<span className='text-center font-bold text-gray-800'>
|
||||
<p className='pb-1 pt-2 text-6xl text-white lg:pb-3 lg:pt-4 lg:text-8xl'>
|
||||
{hours}
|
||||
</p>
|
||||
<p className='text-2xl font-light text-white lg:text-5xl'>
|
||||
{props.hours}
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className='relative h-48 w-48 lg:h-64 lg:w-64'>
|
||||
<div className='absolute inset-0 rotate-[-45deg] overflow-hidden rounded-full bg-[#A9CDF7]'>
|
||||
<div className='absolute left-0 top-0 h-full w-1/2'></div>
|
||||
<div className='absolute right-0 top-0 h-full w-1/2 bg-[#C8E0FC]'></div>
|
||||
</div>
|
||||
<div className='absolute inset-0 flex items-center justify-center'>
|
||||
<span className='text-center font-bold text-gray-800'>
|
||||
<p className='pb-1 pt-2 text-6xl text-white lg:pb-3 lg:pt-4 lg:text-8xl'>
|
||||
{minutes}
|
||||
</p>
|
||||
<p className='text-2xl font-light text-white lg:text-5xl'>
|
||||
{props.minutes}
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default CountDownTimer;
|
|
@ -1,155 +1,194 @@
|
|||
import Link from 'next/link'
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
|
||||
import { getDictionary } from '@/dictionaries';
|
||||
|
||||
import OpenFestLogoWithe from './openfest/openfest-logo-withe.svg';
|
||||
|
||||
const Footer = async ({ lang }) => {
|
||||
const dictionary = await getDictionary(lang);
|
||||
const currentYear = new Date().getFullYear();
|
||||
|
||||
const Footer = () => {
|
||||
return (
|
||||
<footer className='mt-auto'>
|
||||
<div className='bg-dark-blue pt-8 lg:pt-16 pb-6'>
|
||||
<div className='container'>
|
||||
<div className='flex items-center gap-4 mb-3'>
|
||||
<div className='bg-blue w-14 h-14 lg:w-16 lg:h-16 p-1 rounded-full'>
|
||||
<svg
|
||||
className='fill-deep-blue'
|
||||
width='100%'
|
||||
height='100%'
|
||||
viewBox='0 0 293 182'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M0 86.1918L18.5717 65.0594L66.4078 111.895C70.0214 108.957 74.1682 105.87 78.7001 102.753L48.1916 61.7055L65.8746 49.4475L93.4804 93.6119C101.863 89.0114 111.163 84.7374 121.353 81.4429L98.1307 8.48858L133.29 0L147.833 75.4772C153.401 74.8539 159 74.5274 164.627 74.5571L177.601 13.1484L203.104 19.0845L184.917 76.4566C204.2 79.9886 220.283 88.2397 233.168 98.5982L282.663 37.9315L293 47.7557L241.876 106.256C252.095 116.317 259.796 127.566 264.98 138.221L233.257 156.594C233.257 156.594 220.402 126.349 196.202 108.126C198.986 114.537 200.497 121.63 200.497 129.05C200.497 158.196 176.772 182 147.714 182C117.117 182 92.888 155.703 95.0206 125.34L122.004 128.605C118.361 142.05 128.55 155.941 142.916 155.941C154.764 155.941 164.598 146.205 164.598 134.215C164.598 102.308 128.402 94.5023 102.544 105.484C86.4605 112.34 73.5166 122.402 55.8039 136.084C37.7061 119.107 18.8679 102.783 0 86.1918Z'
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<p className='text-xl lg:text-3xl font-extrabold uppercase'>
|
||||
OpenFest
|
||||
</p>
|
||||
<p>2024</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex flex-col lg:flex-row gap-6'>
|
||||
<div className='basis-1/2'>
|
||||
<p>
|
||||
OpenFest е конференция, посветена на свободната култура,
|
||||
свободния софтуер и софтуера с отворен код, свободното споделяне
|
||||
на знания.
|
||||
</p>
|
||||
<div className='flex flex-col gap-4 my-4'>
|
||||
<div className='flex items-center'>
|
||||
<div className='w-10 h-10 bg-blue flex items-center justify-center rounded-full mr-3'>
|
||||
<i className='fa-solid fa-calendar-days'></i>
|
||||
</div>
|
||||
2 и 3 ноември 2024 (събота и неделя)
|
||||
<footer className='bg-[#002A5D] px-12 pt-12 lg:px-9'>
|
||||
<div className='row-gap-6 m-auto mb-8 grid max-w-screen-xl gap-10 sm:grid-cols-2 lg:grid-cols-4'>
|
||||
<div className='sm:col-span-2'>
|
||||
<Image src={OpenFestLogoWithe} alt='OpenFest Logo' width={256} />
|
||||
<div className='mt-6 lg:max-w-sm'>
|
||||
<p className='text-[15px] text-base text-white'>
|
||||
{dictionary.footer.description}
|
||||
</p>
|
||||
<div className='mt-3 flex flex-col'>
|
||||
<div className='my-4 flex items-center'>
|
||||
<div className='mr-3 flex h-10 w-10 items-center justify-center rounded-full bg-[#A9CDF7]'>
|
||||
<i
|
||||
className='fa-solid fa-calendar-days'
|
||||
style={{ color: '#002A5D' }}
|
||||
></i>
|
||||
</div>
|
||||
<div className='flex items-center'>
|
||||
<div className='w-10 h-10 bg-blue flex items-center justify-center rounded-full mr-3'>
|
||||
<i className='fa-solid fa-location-dot'></i>
|
||||
</div>
|
||||
Sofia Tech Park
|
||||
</div>
|
||||
<div className='flex items-center'>
|
||||
<div className='w-10 h-10 bg-blue flex items-center justify-center rounded-full mr-3'>
|
||||
<i className='fa-solid fa-ticket'></i>
|
||||
</div>
|
||||
Вход свободен, без предварителна регистрация
|
||||
<p className='text-base text-white'>
|
||||
{dictionary.footer.eventDate}
|
||||
</p>
|
||||
</div>
|
||||
<div className='flex items-center'>
|
||||
<div className='mr-3 flex h-10 w-10 items-center justify-center rounded-full bg-[#A9CDF7]'>
|
||||
<i
|
||||
className='fa-solid fa-location-dot'
|
||||
style={{ color: '#002A5D' }}
|
||||
></i>
|
||||
</div>
|
||||
<a
|
||||
href='https://maps.app.goo.gl/XsAKbZh7mMR3T8Rk8'
|
||||
target='_blank'
|
||||
className='text-base text-white hover:underline hover:underline-offset-4'
|
||||
>
|
||||
{dictionary.footer.eventLocation}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className='basis-1/4'>
|
||||
<p className='font-extrabold'>Свържете се</p>
|
||||
<p>
|
||||
Ако имате въпроси, предложения или желаете да се включите в
|
||||
OpenFest 2024, пишете ни:
|
||||
</p>
|
||||
<div className='flex flex-col'>
|
||||
<div className='flex items-center my-4'>
|
||||
<div className='w-10 h-10 bg-neon-green text-black flex items-center justify-center rounded-full mr-3'>
|
||||
<i className='fa-solid fa-envelope'></i>
|
||||
</div>
|
||||
<Link href='mailto:info@openfest.org'>info@openfest.org</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex flex-col gap-4 basis-1/4'>
|
||||
<Link href='https://cfp.openfest.org/'>
|
||||
<div className='flex items-center'>
|
||||
<div className='w-10 h-10 bg-neon-green text-black flex items-center justify-center rounded-full mr-3'>
|
||||
<i className='fa-solid fa-lightbulb'></i>
|
||||
</div>
|
||||
Call for Participation
|
||||
</div>
|
||||
</Link>
|
||||
<Link href='https://cfp.openfest.org/'>
|
||||
<div className='flex items-center'>
|
||||
<div className='w-10 h-10 bg-neon-green text-black flex items-center justify-center rounded-full mr-3'>
|
||||
<i className='fa-solid fa-helmet-safety'></i>
|
||||
</div>
|
||||
Call for Volunteers
|
||||
</div>
|
||||
</Link>
|
||||
<Link href='https://cfp.openfest.org/'>
|
||||
<div className='flex items-center'>
|
||||
<div className='w-10 h-10 bg-neon-green text-black flex items-center justify-center rounded-full mr-3'>
|
||||
<i className='fa-solid fa-handshake-angle'></i>
|
||||
</div>
|
||||
Партньорство и спонсорство
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex justify-center gap-4 mt-4'>
|
||||
<div className='w-10 h-10 bg-blue flex items-center justify-center rounded-full'>
|
||||
<a
|
||||
href='https://www.youtube.com/@openfestbulgaria'
|
||||
target='_blank'
|
||||
>
|
||||
<i className='fa-brands fa-youtube'></i>
|
||||
</a>
|
||||
</div>
|
||||
<div className='text-blue text-4xl flex items-center justify-center rounded-full'>
|
||||
<a
|
||||
href='https://www.facebook.com/groups/6360369433'
|
||||
target='_blank'
|
||||
>
|
||||
<i className='fa-brands fa-facebook'></i>
|
||||
</a>
|
||||
</div>
|
||||
<div className='w-10 h-10 bg-blue flex items-center justify-center rounded-full'>
|
||||
<a href='https://twitter.com/openfestbg' target='_blank'>
|
||||
<i className='fa-brands fa-x-twitter'></i>
|
||||
</a>
|
||||
</div>
|
||||
<div className='w-10 h-10 bg-blue flex items-center justify-center rounded-full'>
|
||||
<a href='https://mastodon.social/@openfest' target='_blank'>
|
||||
<i className='fa-brands fa-mastodon'></i>
|
||||
</a>
|
||||
</div>
|
||||
<div className='w-10 h-10 bg-blue flex items-center justify-center rounded-full'>
|
||||
<a
|
||||
href='https://www.instagram.com/openfestbulgaria'
|
||||
target='_blank'
|
||||
>
|
||||
<i className='fa-brands fa-instagram'></i>
|
||||
</a>
|
||||
</div>
|
||||
<div className='w-10 h-10 bg-blue flex items-center justify-center rounded-full'>
|
||||
<a
|
||||
href='https://www.linkedin.com/company/openfest-bulgaria/'
|
||||
target='_blank'
|
||||
>
|
||||
<i className='fa-brands fa-linkedin-in'></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<p className='text-center mt-5'>
|
||||
© 2024 OpenFest. Някои права са запазени.
|
||||
</div>
|
||||
<div className='space-y-2 text-sm'>
|
||||
<p className='text-base font-bold tracking-wide text-gray-900'>
|
||||
Contacts
|
||||
</p>
|
||||
<div className='mt-6 flex basis-1/4 flex-col gap-4'>
|
||||
<a
|
||||
href='mailto:info@openfest.org'
|
||||
target='_blank'
|
||||
className='hover:underline hover:underline-offset-4'
|
||||
>
|
||||
Свържете се
|
||||
<i className='fa-solid fa-angle-right ml-1 text-neon-green'></i>
|
||||
</a>
|
||||
<a
|
||||
href='https://cfp.openfest.org/'
|
||||
target='_blank'
|
||||
className='hover:underline hover:underline-offset-4'
|
||||
>
|
||||
Включете се
|
||||
<i className='fa-solid fa-angle-right ml-1 text-neon-green'></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<span className='text-base font-bold tracking-wide text-white'>
|
||||
{dictionary.footer.contactTeam}
|
||||
</span>
|
||||
<p className='mt-4 text-[15px] text-base text-white'>
|
||||
{dictionary.footer.contactDirections}
|
||||
</p>
|
||||
<div className='mt-0 flex flex-col'>
|
||||
<div className='my-4 flex items-center'>
|
||||
<div className='mr-3 flex h-10 w-10 items-center justify-center rounded-full bg-[#A9CDF7]'>
|
||||
<i
|
||||
className='fa-solid fa-envelope'
|
||||
style={{ color: '#002A5D' }}
|
||||
></i>
|
||||
</div>
|
||||
<a
|
||||
href='mailto:info@openfest.org'
|
||||
target='_blank'
|
||||
className='text-base hover:underline hover:underline-offset-4'
|
||||
>
|
||||
info@openfest.org
|
||||
</a>
|
||||
</div>
|
||||
<div className='flex items-center'>
|
||||
<div className='mr-3 flex h-10 w-10 items-center justify-center rounded-full bg-[#A9CDF7]'>
|
||||
<i
|
||||
className='fa-solid fa-user-plus'
|
||||
style={{ color: '#002A5D' }}
|
||||
></i>
|
||||
</div>
|
||||
<a
|
||||
href='http://cfp.openfest.org/'
|
||||
target='_blank'
|
||||
className='text-base hover:underline hover:underline-offset-4'
|
||||
>
|
||||
Call for participation
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='mb-12 mt-14 flex justify-center gap-7'>
|
||||
<a
|
||||
href='https://www.youtube.com/@openfestbulgaria'
|
||||
target='_blank'
|
||||
className='cursor flex h-12 w-12 items-center justify-center rounded-full bg-[#A9CDF7] text-[#002A5D] hover:bg-white'
|
||||
>
|
||||
<i className='fa-brands fa-youtube fa-xl'></i>
|
||||
</a>
|
||||
<a
|
||||
href='https://www.facebook.com/OpenFestBulgaria'
|
||||
target='_blank'
|
||||
className='cursor flex h-12 w-12 items-center justify-center rounded-full bg-[#A9CDF7] text-[#002A5D] hover:bg-white'
|
||||
>
|
||||
<i className='fa-brands fa-facebook fa-xl'></i>
|
||||
</a>
|
||||
<a
|
||||
href='https://twitter.com/openfestbg'
|
||||
target='_blank'
|
||||
className='cursor flex h-12 w-12 items-center justify-center rounded-full bg-[#A9CDF7] text-[#002A5D] hover:bg-white'
|
||||
>
|
||||
<i className='fa-brands fa-x-twitter fa-xl'></i>
|
||||
</a>
|
||||
<a
|
||||
href='https://mastodon.social/@openfest'
|
||||
target='_blank'
|
||||
className='cursor flex h-12 w-12 items-center justify-center rounded-full bg-[#A9CDF7] text-[#002A5D] hover:bg-white'
|
||||
>
|
||||
<i className='fa-brands fa-mastodon fa-xl'></i>
|
||||
</a>
|
||||
<a
|
||||
href='https://www.instagram.com/openfestbulgaria'
|
||||
target='_blank'
|
||||
className='cursor flex h-12 w-12 items-center justify-center rounded-full bg-[#A9CDF7] text-[#002A5D] hover:bg-white'
|
||||
>
|
||||
<i className='fa-brands fa-instagram fa-xl'></i>
|
||||
</a>
|
||||
<a
|
||||
href='https://www.linkedin.com/company/openfest-bulgaria/'
|
||||
target='_blank'
|
||||
className='cursor flex h-12 w-12 items-center justify-center rounded-full bg-[#A9CDF7] text-[#002A5D] hover:bg-white'
|
||||
>
|
||||
<i className='fa-brands fa-linkedin-in fa-xl'></i>
|
||||
</a>
|
||||
</div>
|
||||
<div className='m-auto flex max-w-screen-xl flex-col-reverse justify-between border-t border-[#F2F5F9] pb-10 pt-5 lg:flex-row'>
|
||||
<p className='text-sm text-[#F2F5F9]'>
|
||||
© {currentYear} OpenFest. {dictionary.footer.copyright}
|
||||
</p>
|
||||
<ul className='mb-3 flex flex-col space-y-2 sm:flex-row sm:space-x-5 sm:space-y-0 lg:mb-0'>
|
||||
<li>
|
||||
<a
|
||||
href='/'
|
||||
className='hover:text-deep-purple-accent-400 text-sm text-gray-600 transition-colors duration-300'
|
||||
>
|
||||
F.A.Q
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href='/'
|
||||
className='hover:text-deep-purple-accent-400 text-sm text-gray-600 transition-colors duration-300'
|
||||
>
|
||||
Privacy Policy
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href='/'
|
||||
className='hover:text-deep-purple-accent-400 text-sm text-gray-600 transition-colors duration-300'
|
||||
>
|
||||
Terms & Conditions
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer
|
||||
export default Footer;
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
import Chicken from './icons/Chicken'
|
||||
|
||||
const Header = () => {
|
||||
return (
|
||||
<header className='relative overflow-hidden pt-10 pb-16 sm:pt-16 sm:pb-24 lg:pt-16 lg:pb-44 bg-deep-blue'>
|
||||
<div className='container flex flex-col gap-2 lg:gap-4 text-center'>
|
||||
<p className='uppercase tracking-widest lg:tracking-max text-xl lg:text3xl z-10'>
|
||||
2 - 3 Ноември 2024
|
||||
</p>
|
||||
<p className='font-extrabold text-4xl lg:text-8xl z-10'>OpenFest</p>
|
||||
<p className='font-extrabold text-4xl lg:text-8xl z-10'>2024</p>
|
||||
</div>
|
||||
<Chicken className='fill-blue absolute inset-0 scale-1.3 -translate-y-10 sm:scale-125 lg:-translate-y-16' />
|
||||
</header>
|
||||
)
|
||||
}
|
||||
|
||||
export default Header
|
|
@ -1,59 +0,0 @@
|
|||
import Circle from './icons/Circle'
|
||||
import Eye from './icons/Eye'
|
||||
|
||||
const Info = () => {
|
||||
return (
|
||||
<div className='bg-deep-blue'>
|
||||
<div className='container'>
|
||||
<div className='flex flex-col-reverse lg:flex-row gap-6 items-center py-8 lg:py-16'>
|
||||
<div className='flex justify-center relative flex-1'>
|
||||
<Circle className='w-2/5 md:w-1/2' />
|
||||
<Eye className='absolute inset-0 translate-x-full w-2/5 md:translate-x-3/4 md:w-1/2' />
|
||||
</div>
|
||||
<div className='flex-1'>
|
||||
<h2 className='font-extrabold text-xl lg:text-3xl'>
|
||||
{' '}
|
||||
Повече за OpenFest
|
||||
</h2>
|
||||
<p className='mt-4 mb-2'>
|
||||
OpenFest e най-голямата българска конференция, посветена на
|
||||
свободната култура, свободния софтуер и софтуера с отворен код,
|
||||
свободното споделяне на знания – фестивал на свободното
|
||||
творчество.
|
||||
</p>
|
||||
<p>
|
||||
Организаторите всякога се стараят да дадат поле за изява и на
|
||||
свободното изкуство и свободното разпространение на знания.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='bg-blue'>
|
||||
<div className='container flex flex-col gap-2 items-center lg:gap-0 lg:flex-row lg:justify-between p-2'>
|
||||
<p>
|
||||
<i className='fa-solid fa-angle-right text-neon-pink'></i>
|
||||
1500+ посетители годишно
|
||||
</p>
|
||||
<p>
|
||||
<i className='fa-solid fa-angle-right text-neon-pink'></i>
|
||||
40+ Лектора
|
||||
</p>
|
||||
<p>
|
||||
<i className='fa-solid fa-angle-right text-neon-pink'></i>
|
||||
20+ Лекции
|
||||
</p>
|
||||
<p>
|
||||
<i className='fa-solid fa-angle-right text-neon-pink'></i>
|
||||
20+ Работилници
|
||||
</p>
|
||||
<p>
|
||||
<i className='fa-solid fa-angle-right text-neon-pink'></i>
|
||||
70+ Доброволеца
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Info
|
|
@ -1,155 +0,0 @@
|
|||
import Link from 'next/link'
|
||||
import BackToTheSource from './icons/BackToTheSource'
|
||||
|
||||
export default function JoinUs() {
|
||||
return (
|
||||
<div className='container flex flex-col pt-8 lg:pt-16 gap-8 lg:gap-16'>
|
||||
<div className='flex flex-col-reverse text-black lg:flex-row gap-6 items-center'>
|
||||
<div className='flex-1'>
|
||||
<h2 className='font-extrabold text-xl lg:text-3xl'>
|
||||
Станете част от OpenFest 2024
|
||||
</h2>
|
||||
<p className='mt-4 mb-2'>
|
||||
Фестът е оживен двудневен празник на всичко с отворен код, който
|
||||
събира ентусиасти, разработчици и новатори. Независимо дали сте
|
||||
опитен професионалист или начинаещ, OpenFest предлага уникална
|
||||
възможност да се потопите в света на отворените технологии и
|
||||
съвместното творчество във всички измерения.
|
||||
</p>
|
||||
<div className='flex flex-col gap-2 mt-4'>
|
||||
<div className='flex items-center'>
|
||||
<div className='w-10 h-10 bg-blue flex items-center justify-center rounded-full mr-3 text-white min-w-10'>
|
||||
<i className='fa-solid fa-calendar-days'></i>
|
||||
</div>
|
||||
2 и 3 ноември 2024 (събота и неделя)
|
||||
</div>
|
||||
<div className='flex items-center'>
|
||||
<div className='w-10 h-10 bg-blue flex items-center justify-center rounded-full mr-3 text-white min-w-10'>
|
||||
<i className='fa-solid fa-location-dot'></i>
|
||||
</div>
|
||||
Sofia Tech Park
|
||||
</div>
|
||||
<div className='flex items-center'>
|
||||
<div className='w-10 h-10 bg-blue flex items-center justify-center rounded-full mr-3 min-w-10 text-blue'>
|
||||
<i className='fa-solid fa-location-dot'></i>
|
||||
</div>
|
||||
Вход свободен, без предварителна регистрация
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex justify-center relative flex-1'>
|
||||
<BackToTheSource />
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex flex-col text-black lg:flex-row gap-6 items-center'>
|
||||
<div className='flex flex-col gap-4 items-center center relative flex-1'>
|
||||
<div className='flex items-center justify-center bg-blue rounded-full p-4 text-5xl w-24 h-24 lg:text-7xl lg:w-36 lg:h-36'>
|
||||
<i className='fa-regular fa-lightbulb text-neon-pink'></i>
|
||||
</div>
|
||||
<h2 className='font-extrabold text-3xl text-center'>
|
||||
Предложете
|
||||
<br />
|
||||
идея
|
||||
</h2>
|
||||
</div>
|
||||
<div className='flex-1'>
|
||||
<p className='mb-2'>
|
||||
Представете лекция, уъркшоп или щанд. Приемаме предложения до 1
|
||||
септември 2024 г
|
||||
</p>
|
||||
<p>Тази година направленията са:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Advanced Technical</strong> – За технически лекции с
|
||||
по-голяма сложност.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Technical</strong> – Това е мястото да разкажете какво
|
||||
ново сте открили през годината, което би било полезно и разбираемо
|
||||
и за начинаещи.
|
||||
</li>
|
||||
<li>
|
||||
<strong>OpenArt</strong> – Свободата да твориш под Creative
|
||||
Commons и свободното изкуство във всичките му форми.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Общност и социален</strong> – Отворени общности,
|
||||
образование и управление, свободни лицензи, как човек може да се
|
||||
изхранва с хобито си и др.
|
||||
</li>
|
||||
</ul>
|
||||
<div className='flex justify-center mt-4'>
|
||||
<Link
|
||||
href='https://cfp.openfest.org/'
|
||||
className='bg-neon-green px-16 py-4 rounded-md'
|
||||
>
|
||||
Предложете идея
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex flex-col-reverse text-black lg:flex-row gap-6 items-center'>
|
||||
<div className='flex-1'>
|
||||
<p>
|
||||
OpenFest се организира и провежда изцяло от доброволци. Тази година
|
||||
отново се надяваме да срещнем нови съмишленици и приятели, да
|
||||
създадем вълнуващо събитие. Можете да се включите в екипите: Мрежа;
|
||||
Логистика; Аудио и видео; Медия, уебсайт и дизайн; Хералди;
|
||||
Рецепция.
|
||||
</p>
|
||||
<p className='mt-4'>
|
||||
Повече за тях можете да прочетете във формата за кандидатстване.
|
||||
</p>
|
||||
<div className='flex justify-center mt-4'>
|
||||
<Link
|
||||
href='https://cfp.openfest.org/'
|
||||
className='bg-neon-green px-16 py-4 rounded-md'
|
||||
>
|
||||
Кандидатствайте
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex flex-col gap-4 items-center center relative flex-1'>
|
||||
<div className='flex items-center justify-center bg-blue rounded-full p-4 text-5xl w-24 h-24 lg:text-7xl lg:w-36 lg:h-36'>
|
||||
<i className='fa-solid fa-helmet-safety text-neon-pink'></i>
|
||||
</div>
|
||||
<h2 className='font-extrabold text-3xl text-center'>
|
||||
Станете
|
||||
<br />
|
||||
доброволец
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex flex-col text-black lg:flex-row gap-6 items-center'>
|
||||
<div className='flex flex-col gap-4 items-center center relative flex-1'>
|
||||
<div className='flex items-center justify-center bg-blue rounded-full p-4 text-5xl w-24 h-24 lg:text-7xl lg:w-36 lg:h-36'>
|
||||
<i className='fa-solid fa-handshake-angle text-neon-pink'></i>
|
||||
</div>
|
||||
<h2 className='font-extrabold text-3xl text-center'>
|
||||
Подкрепете <br /> събитието като <br /> партньор
|
||||
</h2>
|
||||
</div>
|
||||
<div className='flex-1'>
|
||||
<p>
|
||||
OpenFest се организира и провежда изцяло от доброволци. Тази година
|
||||
отново се надяваме да срещнем нови съмишленици и приятели, да
|
||||
създадем вълнуващо събитие. Можете да се включите в екипите: Мрежа;
|
||||
Логистика; Аудио и видео; Медия, уебсайт и дизайн; Хералди;
|
||||
Рецепция.
|
||||
</p>
|
||||
<p className='mt-4'>
|
||||
Повече за тях можете да прочетете във формата за кандидатстване.
|
||||
</p>
|
||||
<div className='flex justify-center mt-4'>
|
||||
<Link
|
||||
href='https://cfp.openfest.org/'
|
||||
className='bg-neon-green px-16 py-4 rounded-md'
|
||||
>
|
||||
Кандидатствайте
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -1,30 +1,30 @@
|
|||
'use client'
|
||||
|
||||
import Link from 'next/link'
|
||||
import { i18n } from '../../i18n-config'
|
||||
import { usePathname } from 'next/navigation'
|
||||
'use client';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import Link from 'next/link';
|
||||
import { i18n } from '../../i18n-config';
|
||||
|
||||
export default function LocaleSwitcher({ lang }) {
|
||||
const pathName = usePathname()
|
||||
const pathName = usePathname();
|
||||
|
||||
const { locales } = i18n
|
||||
const otherLocale = locales?.find((cur) => cur !== lang)
|
||||
const { locales } = i18n;
|
||||
const otherLocale = locales?.find((cur) => cur !== lang);
|
||||
|
||||
function getRedirectPathName() {
|
||||
if (!pathName) return '/'
|
||||
const segments = pathName.split('/')
|
||||
segments[1] = otherLocale
|
||||
if (!pathName) return '/';
|
||||
const segments = pathName.split('/');
|
||||
segments[1] = otherLocale;
|
||||
|
||||
return segments.join('/')
|
||||
return segments.join('/');
|
||||
}
|
||||
|
||||
return (
|
||||
<Link
|
||||
href={getRedirectPathName()}
|
||||
locale={otherLocale}
|
||||
className='flex justify-center items-center'
|
||||
className='flex items-center justify-center'
|
||||
>
|
||||
<i className='fa-solid fa-globe'></i>
|
||||
<i className='fa-solid fa-globe text-black'></i>
|
||||
<div className='pl-2'>{lang === 'en' ? 'БГ' : 'EN'}</div>
|
||||
</Link>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
// import Logo from './icons/Logo'
|
||||
import LanguageSwitcher from './LanguageSwitcher';
|
||||
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
// import {
|
||||
// DisclosureButton,
|
||||
// Menu,
|
||||
// MenuButton,
|
||||
// MenuItem,
|
||||
// MenuItems,
|
||||
// Transition,
|
||||
// } from '@headlessui/react';
|
||||
// import { BookmarkIcon } from '@heroicons/react';
|
||||
|
||||
import { getDictionary } from '@/dictionaries';
|
||||
|
||||
import OpenFestLogo from './openfest/openfest-logo.svg';
|
||||
|
||||
// const navigation = [
|
||||
// { name: 'Dashboard', href: '#', current: true },
|
||||
// { name: 'Team', href: '#', current: false },
|
||||
// { name: 'Projects', href: '#', current: false },
|
||||
// { name: 'Calendar', href: '#', current: false },
|
||||
// ];
|
||||
|
||||
// function classNames(...classes) {
|
||||
// return classes.filter(Boolean).join(' ')
|
||||
// }
|
||||
|
||||
const open = true;
|
||||
|
||||
const NavBar = async ({ lang }) => {
|
||||
const dictionary = await getDictionary(lang);
|
||||
|
||||
return (
|
||||
<>
|
||||
<nav className='container flex flex-col items-center justify-between gap-4 bg-white text-black sm:flex-row'>
|
||||
<div>
|
||||
<a href='https://openfest.org/' className='flex items-center'>
|
||||
<Image src={OpenFestLogo} alt='OpenFest Logo' width={256} />
|
||||
</a>
|
||||
</div>
|
||||
<div className='flex items-center justify-center'>
|
||||
<ul className='flex flex-wrap items-center justify-center gap-4 sm:gap-8'>
|
||||
<li>
|
||||
<a href='#' className='' aria-current='page'>
|
||||
{dictionary.nav.home}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href='#' className=''>
|
||||
{dictionary.nav.about}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href='#' className=''>
|
||||
{dictionary.nav.partners}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href='#' className=''>
|
||||
{dictionary.nav.archive}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href='#' className=''>
|
||||
{dictionary.nav.contact}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<LanguageSwitcher lang={lang} />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{
|
||||
//<div className='mx-auto flex max-w-screen-xl flex-wrap items-center justify-between p-4'>
|
||||
// <div
|
||||
// className='hidden w-full md:block md:w-auto'
|
||||
// id='navbar-default'
|
||||
// >
|
||||
// // </div>
|
||||
//</div>
|
||||
}
|
||||
</nav>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default NavBar;
|
|
@ -1,31 +0,0 @@
|
|||
import Logo from './icons/Logo'
|
||||
import LanguageSwitcher from './LanguageSwitcher'
|
||||
import Link from 'next/link'
|
||||
|
||||
const Navbar = ({ lang }) => {
|
||||
return (
|
||||
<nav className='bg-deep-blue'>
|
||||
<div className='container flex flex-col items-center gap-6 lg:flex-row lg:justify-between py-6'>
|
||||
<Link href='/' className='flex items-center gap-4'>
|
||||
<div className='bg-blue w-14 h-14 lg:w-16 lg:h-16 p-1 rounded-full'>
|
||||
<Logo className='fill-deep-blue' />
|
||||
</div>
|
||||
<div>
|
||||
<p className='text-xl lg:text-3xl font-extrabold uppercase'>
|
||||
OpenFest
|
||||
</p>
|
||||
<p>2024</p>
|
||||
</div>
|
||||
</Link>
|
||||
<div className='flex w-full flex-wrap justify-center sm:justify-around lg:justify-end gap-6 gap-y-4 items-center font-semibold'>
|
||||
<Link href='/news'>Новини</Link>
|
||||
<Link href='https://cfp.openfest.org/'>Call for participation</Link>
|
||||
<Link href='mailto:info@openfest.org'>Пишете ни</Link>
|
||||
<LanguageSwitcher lang={lang} />
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
||||
export default Navbar
|
|
@ -1,21 +0,0 @@
|
|||
import Link from 'next/link'
|
||||
|
||||
export default function News({ posts }) {
|
||||
return (
|
||||
<div className='flex flex-wrap text-center gap-6 lg:text-left lg:gap-4 lg:gap-y-8'>
|
||||
{posts.map((post) => (
|
||||
<div key={post.id} className='flex flex-col gap-2 basis-24 flex-1'>
|
||||
<p className='text-xl font-extrabold'>{post.title}</p>
|
||||
<p>{post.date}</p>
|
||||
<p>{post.truncatedContent}</p>
|
||||
<Link href={`/news/post/${post.id}`}>
|
||||
<p className='underline decoration-2 underline-offset-4 decoration-neon-green mt-auto'>
|
||||
Прочетете
|
||||
<i className='fa-solid fa-angle-right text-neon-green ml-1'></i>
|
||||
</p>
|
||||
</Link>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
import Image from 'next/image';
|
||||
import { getDictionary } from '@/dictionaries';
|
||||
import { getSortedPostsData } from '@/lib/posts';
|
||||
|
||||
const NewsFeed = async ({ lang }) => {
|
||||
const dictionary = await getDictionary(lang);
|
||||
const posts = await getSortedPostsData(lang);
|
||||
|
||||
return (
|
||||
<section className='bg-blue-8'>
|
||||
<div className='container flex flex-col gap-4 sm:gap-8'>
|
||||
<h2 className='text-center text-2xl text-blue-2 sm:text-start sm:text-4xl'>
|
||||
{dictionary.main.news.title}
|
||||
</h2>
|
||||
<div className='flex flex-col gap-4 sm:flex-row sm:gap-8'>
|
||||
{posts.map((post) => {
|
||||
return (
|
||||
<div
|
||||
key={post.title}
|
||||
className='flex basis-1/3 flex-col overflow-hidden rounded-xl drop-shadow-2xl'
|
||||
>
|
||||
<div>
|
||||
<Image src={post.imageUrl} width='400' height='190'></Image>
|
||||
</div>
|
||||
<div className='flex h-full flex-1 flex-col gap-2 bg-white p-6 text-center sm:gap-4'>
|
||||
<p className='text-blue-2'>{post.title}</p>
|
||||
<p className='text-sm opacity-50'>{post.date}</p>
|
||||
<a
|
||||
href='#'
|
||||
className='mx-auto mt-auto self-baseline rounded-3xl bg-blue-2 px-12 py-2'
|
||||
>
|
||||
{dictionary.main.news.cardButton}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<a
|
||||
href='#'
|
||||
className='mt-4 flex items-center justify-center gap-4 self-center rounded-3xl bg-blue-2 px-12 py-2 sm:self-baseline'
|
||||
>
|
||||
{dictionary.main.news.button}
|
||||
<i className='fa-solid fa-arrow-right'></i>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default NewsFeed;
|
|
@ -0,0 +1,61 @@
|
|||
import Image from 'next/image';
|
||||
|
||||
import { getDictionary } from '@/dictionaries';
|
||||
|
||||
const Partners = async ({ lang }) => {
|
||||
const dictionary = await getDictionary(lang);
|
||||
const sponsorLogos = ['logo-1', 'logo-2', 'logo-3', 'logo-4', 'logo-5'];
|
||||
const mediaPartnerLogos = ['logo-1', 'logo-2', 'logo-3', 'logo-4', 'logo-5'];
|
||||
|
||||
const getShuffledLogos = (logos) => {
|
||||
for (let i = logos.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
|
||||
[logos[i], logos[j]] = [logos[j], logos[i]];
|
||||
}
|
||||
return logos;
|
||||
};
|
||||
|
||||
return (
|
||||
<section>
|
||||
<div className='container flex flex-col gap-10 !py-16 sm:gap-16'>
|
||||
<div>
|
||||
<h2 className='pb-4 text-center text-2xl text-blue-2 sm:pb-8 sm:text-4xl'>
|
||||
{dictionary.main.partners.sponsors}
|
||||
</h2>
|
||||
<div className='flex flex-wrap justify-evenly gap-6'>
|
||||
{getShuffledLogos(sponsorLogos).map((logo) => {
|
||||
return (
|
||||
<div
|
||||
key={logo}
|
||||
className='cursor-pointer opacity-50 hover:opacity-100'
|
||||
>
|
||||
<p>{logo}</p>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h2 className='pb-4 text-center text-2xl text-blue-2 sm:pb-8 sm:text-4xl'>
|
||||
{dictionary.main.partners.media}
|
||||
</h2>
|
||||
<div className='flex flex-wrap justify-evenly gap-6'>
|
||||
{getShuffledLogos(mediaPartnerLogos).map((logo) => {
|
||||
return (
|
||||
<div
|
||||
key={logo}
|
||||
className='cursor-pointer opacity-50 hover:opacity-100'
|
||||
>
|
||||
<p>{logo}</p>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Partners;
|
|
@ -1,57 +0,0 @@
|
|||
const Social = () => {
|
||||
return (
|
||||
<div id='social' className='py-8 lg:pb-16 bg-deep-blue'>
|
||||
<div className='container'>
|
||||
<h2 className='font-extrabold text-center text-xl lg:text-3xl mb-6 lg:mb-12'>
|
||||
Продължете разговора
|
||||
</h2>
|
||||
<div className='flex flex-wrap justify-center gap-10 md:gap-20 md:gap-y-12'>
|
||||
<div className='flex items-center gap-4'>
|
||||
<div className='flex justify-center items-center bg-neon-green w-12 h-12 md:w-16 md:h-16 rounded-full text-black text-3xl'>
|
||||
<i className='fa-brands fa-youtube'></i>
|
||||
</div>
|
||||
@openfestbulgaria
|
||||
</div>
|
||||
<div className='flex items-center gap-4'>
|
||||
<div className='flex justify-center items-center bg-black w-12 h-12 md:w-16 md:h-16 rounded-full text-neon-green text-5xl md:text-6xl'>
|
||||
<i className='fa-brands fa-facebook '></i>
|
||||
</div>
|
||||
@openfestbulgaria
|
||||
</div>
|
||||
<div className='flex items-center gap-4'>
|
||||
<div className='flex justify-center items-center bg-neon-green w-12 h-12 md:w-16 md:h-16 rounded-full text-black text-3xl'>
|
||||
<i className='fa-brands fa-x-twitter'></i>
|
||||
</div>
|
||||
OpenFestBG
|
||||
</div>
|
||||
<div className='flex items-center gap-4'>
|
||||
<div className='flex justify-center items-center bg-neon-green w-12 h-12 md:w-16 md:h-16 rounded-full text-black text-3xl'>
|
||||
<i className='fa-brands fa-instagram'></i>
|
||||
</div>
|
||||
openfestbulgaria
|
||||
</div>
|
||||
<div className='flex items-center gap-4'>
|
||||
<div className='flex justify-center items-center bg-neon-green w-12 h-12 md:w-16 md:h-16 rounded-full text-black text-3xl'>
|
||||
<i className='fa-brands fa-mastodon'></i>
|
||||
</div>
|
||||
@openfest
|
||||
</div>
|
||||
<div className='flex items-center gap-4'>
|
||||
<div className='flex justify-center items-center bg-neon-green w-12 h-12 md:w-16 md:h-16 rounded-full text-black text-3xl'>
|
||||
<i className='fa-brands fa-facebook-f'></i>
|
||||
</div>
|
||||
Facebook група: OpenFest
|
||||
</div>
|
||||
<div className='flex items-center gap-4'>
|
||||
<div className='flex justify-center items-center bg-neon-green w-12 h-12 md:w-16 md:h-16 rounded-full text-black text-3xl'>
|
||||
<i className='fa-brands fa-linkedin-in'></i>
|
||||
</div>
|
||||
openfest-bulgaria
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Social
|
|
@ -1,196 +0,0 @@
|
|||
export default function BackToTheSource({ className }) {
|
||||
return (
|
||||
<svg
|
||||
className={className}
|
||||
width='100%'
|
||||
fill='none'
|
||||
viewBox='0 0 710 319'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<path
|
||||
d='M563.902 292.433C502.395 305.069 425.252 313.559 342.093 313.559C144.143 313.559 5.02502 265.455 5.02502 227.837'
|
||||
stroke='#D92ACE'
|
||||
strokeLinecap='round'
|
||||
strokeWidth='10'
|
||||
/>
|
||||
<path
|
||||
d='M703.912 227.837C703.912 241.271 683.012 256.043 647.124 269.484'
|
||||
stroke='#D92ACE'
|
||||
strokeLinecap='round'
|
||||
strokeWidth='10'
|
||||
/>
|
||||
<path
|
||||
d='M636.889 268.756L626.209 281.882C628.085 283.785 629.533 285.587 630.453 286.816C630.536 286.931 630.628 287.061 630.725 287.198C630.867 287.402 631.022 287.626 631.178 287.853C631.332 288.078 631.486 288.307 631.634 288.526C631.649 288.55 631.661 288.573 631.674 288.596C631.679 288.609 631.685 288.621 631.688 288.633C631.732 288.747 631.734 288.87 631.699 288.982C631.692 289.001 631.686 289.022 631.678 289.042C631.67 289.054 631.664 289.067 631.656 289.08C631.648 289.096 631.638 289.111 631.628 289.126C631.591 289.179 631.543 289.227 631.485 289.265L629.694 290.449L629.68 290.458L623.253 294.709C623.008 294.871 622.679 294.804 622.518 294.56L621.658 293.266C621.494 293.021 621.561 292.691 621.806 292.528L624.068 291.031C623.285 289.698 620.987 286.121 617.506 283.534C617.438 283.483 617.347 283.543 617.361 283.623C618.161 288.135 616.542 292.934 612.724 296.014C607.14 300.52 598.966 299.641 594.462 294.054C593.781 293.214 593.222 292.314 592.785 291.375C592.638 291.056 592.841 290.684 593.188 290.631L599.924 289.594C600.099 289.566 600.276 289.631 600.396 289.761C602.406 291.942 605.793 292.222 608.138 290.33C610.576 288.355 610.96 284.781 608.994 282.333C608.985 282.324 608.979 282.316 608.972 282.307C607.981 281.103 606.463 280.598 604.898 280.627C601.804 280.687 597.733 281.872 593.885 283.917C590.477 285.727 587.219 288.392 585.177 290.21C584.548 290.772 584.031 291.256 583.668 291.607C583.45 291.817 583.099 291.802 582.901 291.574L578.791 286.866L571.092 279.166C570.953 279.026 570.903 278.821 570.961 278.634L572.776 272.738C572.895 272.356 573.375 272.235 573.658 272.518L583.049 281.913C583.961 281.215 584.974 280.482 586.069 279.752L582.143 273.801C582.056 273.67 582.032 273.505 582.08 273.354L583.627 268.323C583.759 267.895 584.328 267.812 584.576 268.185L590.523 277.102C591.092 276.804 591.672 276.518 592.262 276.244C593.543 275.651 594.802 275.152 596.03 274.734L593.265 262.643C593.227 262.474 593.274 262.298 593.388 262.17L599.412 255.488C599.699 255.169 600.226 255.306 600.323 255.726L604.268 272.975C605.441 272.869 606.542 272.833 607.558 272.847L611.097 259.71C611.204 259.309 611.715 259.182 611.998 259.487L615.478 263.24C615.601 263.374 615.648 263.561 615.6 263.738L612.982 273.504C612.998 273.508 613.015 273.513 613.031 273.517C617.189 274.63 620.878 277.071 623.851 279.661L635.523 265.422C635.807 265.076 636.364 265.213 636.454 265.652C636.682 266.758 636.997 268.315 636.997 268.315C637.028 268.471 636.989 268.633 636.889 268.756Z'
|
||||
fill='#D92ACE'
|
||||
/>
|
||||
<path
|
||||
d='M631.634 288.526C631.486 288.307 631.332 288.078 631.178 287.853C631.023 287.626 630.867 287.401 630.725 287.198C630.735 287.209 630.743 287.22 630.751 287.232C631.029 287.63 631.347 288.098 631.634 288.526Z'
|
||||
fill='#D92ACE'
|
||||
/>
|
||||
<path
|
||||
d='M631.634 288.526C631.65 288.55 631.662 288.573 631.674 288.596C631.661 288.573 631.649 288.55 631.634 288.526Z'
|
||||
fill='#D92ACE'
|
||||
/>
|
||||
<path
|
||||
d='M631.7 288.981C631.734 288.869 631.732 288.747 631.689 288.633C631.734 288.747 631.736 288.869 631.7 288.981Z'
|
||||
fill='#D92ACE'
|
||||
/>
|
||||
<path
|
||||
d='M4.26318 179.068V173.831L40.1095 198.998V209.139L33.1999 207.054L40.1095 214.671V224.813L8.75892 202.802V182.225L4.26318 179.068ZM16.6344 192.806L26.2898 199.584L32.2339 200.586V198.705L16.6339 187.753L16.6344 192.806ZM16.6344 203.094L32.2345 214.047V212.166L26.2903 204.822L16.635 198.043L16.6344 203.094Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M44.8984 226.151L53.3013 208.784L49.0308 207.152V201.915L72.9646 211.059L83.4333 240.874L74.1351 237.321L71.5177 229.867L56.8481 224.263L54.2306 229.716L44.8984 226.151ZM58.983 219.843L69.3827 223.816L65.7323 213.534L62.6329 212.35L58.983 219.843Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M83.4746 220.236V214.999L125.788 226.289V235.804L116.492 231.995V229.045L98.0778 224.132V239.473L116.492 244.386V241.436L125.788 242.589V252.104L88.7817 242.229V221.652L83.4746 220.236Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M130.03 248.834V242.233L135.427 241.779V228.281L144.88 230.069V240.949L163.389 239.361V233.57L172.842 235.359V245.169L158.644 246.391L166.794 254.498L173.06 255.683V261.215L161.179 258.967L149.263 247.162L144.88 247.55V255.884L135.427 254.095V248.38L130.03 248.834Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M190.567 248.341V238.016L231.526 242.899V253.224L221.973 250.758V246.996L215.823 246.263V266.841L206.27 265.702V245.125L200.12 244.391V248.153L190.567 248.341Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M236.663 269.16V243.346L274.856 246.205V272.02L236.663 269.16ZM246.257 264.642L265.262 266.064V250.723L246.257 249.3V264.642Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M292.153 257.404V247.077L333.389 248.083V258.409L323.771 256.847V253.085L317.58 252.934V273.512L307.962 273.277V252.7L301.771 252.549V256.31L292.153 257.404Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M336.884 253.391V248.154L351.995 247.926V258.142L371.014 257.854V247.639L380.634 247.494V273.308L371.014 273.453V263.09L351.995 263.378V273.74L342.376 273.886V253.308L336.884 253.391Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M385.287 252.636V247.399L429.052 245.016V254.53L419.445 253.725V250.775L400.414 251.812V256.864L416.058 256.012V261.249L400.414 262.101V267.153L419.445 266.116V263.166L429.052 261.315V270.829L390.809 272.912V252.334L385.287 252.636Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M449.991 269.131V260.649L459.559 261.036V262.88L478.108 260.916V257.67L449.991 256.187V243.316L487.675 239.325V248.287L478.107 247.825V245.575L459.559 247.54V251.044L487.675 252.528V265.14L449.991 269.131Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M493.776 264.387V238.573L531.666 232.986V258.802L493.776 264.387ZM503.293 257.748L522.148 254.967V239.626L503.293 242.406V257.748Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M536.277 237.581V232.345L551.098 229.383V247.453L555.725 249.035L569.75 246.232V225.655L579.185 223.77V249.584L553.194 254.778L541.663 250.813V236.505L536.277 237.581Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M583.769 242.965V237.248L589.071 234.891V221.468L626.041 211.457V224.143L615.295 228.933L627.5 236.876L614.655 240.354L604.514 233.734L598.358 236.47V244.767L589.071 247.282V240.608L583.769 242.965ZM598.358 230.68L616.754 222.49V219.207L598.358 224.19V230.68Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M630.358 215.744V210.508L671.111 194.471V203.985L662.157 206.181V203.231L644.422 210.209V225.55L662.157 218.572V215.621L671.111 210.77V220.285L635.469 234.31V213.732L630.358 215.744Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M676.633 199.679V194.443L709.429 165.354V174.868L702.23 179.926V176.976L687.969 189.624V194.677L699.692 184.279V189.515L687.969 199.913V204.966L702.23 192.317V189.367L709.429 181.653V191.168L680.77 216.587V196.009L676.633 199.679Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M9.02502 88.5303V62.7158L41.509 42.4174V68.2319L9.02502 88.5303ZM17.1851 78.195L33.3485 68.0942V52.7533L17.1851 62.8535V78.195Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M46.16 61.7082V55.9184L51.3779 53.2808V39.2672L87.7623 27.3013V40.6512L60.5178 54.4421V62.0759L51.3779 65.0817V59.0706L46.16 61.7082ZM60.5178 48.6522L78.6224 39.4899V35.5441L60.5178 41.4979V48.6522Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M91.6941 31.5751V26.3386L134.507 16.9479V26.4623L125.109 27.1961V24.246L106.494 28.329V33.3815L121.796 30.025V35.2616L106.494 38.6185V43.6705L125.109 39.5875V36.6374L134.507 33.2484V42.7629L97.0955 50.9691V30.3912L91.6941 31.5751Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M140.397 41.7753V14.9285L168.735 26.5561V16.7833L165.639 17.2655V12.0289L178.242 10.0658V35.8803L170.192 37.1344L149.905 28.494V35.0583L153 34.5757V39.8122L140.397 41.7753Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M182.864 14.6865V9.44997L223.359 5.04932V14.3792L213.794 14.0909V11.3249L197.89 13.0534V19.9127L213.794 18.1842V23.4208L197.89 25.1493V33.6314L188.325 34.6704V14.093L182.864 14.6865Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M226.822 9.93122V4.69468L270.551 1.72705V11.2415L260.952 10.5655V7.61539L241.938 8.90557V13.958L257.569 12.8968V18.1333L241.938 19.194V24.2465L260.952 22.9563V20.0062L270.551 18.0271V27.5416L232.339 30.1348V9.55685L226.822 9.93122Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M276.363 27.2867V18.8052L285.978 19.8886V21.7326L304.62 21.1158V17.8708L276.363 14.3431V1.47275L314.237 0.220215V9.18137L304.621 8.02423V5.7744L285.979 6.39113V9.89453L314.237 13.4222V26.0342L276.363 27.2867Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M319.207 10.4932V0.167588L360.456 0V10.3256L350.834 9.03696V5.27521L344.642 5.30048V25.8784L335.02 25.9176V5.33967L328.827 5.36493V9.12669L319.207 10.4932Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M379.62 26.2487V13.747L408.609 10.3076V6.80416L389.234 6.04666V8.29597L379.62 9.39536V0.434204L418.223 1.94354V14.8139L389.234 18.2534V21.3881L408.609 22.1456V20.3016L418.223 19.2759V27.7581L379.62 26.2487Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M424.366 28.0948V2.28027L462.202 4.9612V30.7757L424.366 28.0948ZM433.963 19.5188L448.598 9.23448L433.963 8.19749V19.5188ZM437.971 23.822L452.606 24.859V13.5377L437.971 23.822Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M468.333 31.2975V18.7959L497.185 17.2582V13.7548L477.901 11.7261V13.9755L468.333 14.4442V5.48303L506.753 9.52478V22.3952L477.901 23.9324V27.0671L497.184 29.0957V27.2517L506.753 26.8567V35.3383L468.333 31.2975Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M511.534 32.4187V27.1451L546.994 13.6234V32.3203L552.612 33.1345V38.371L546.994 37.5568V41.0236L537.472 39.6437V36.1774L511.534 32.4187ZM523.791 28.9581L537.472 30.9409V23.7128L523.791 28.9581Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M10.4181 143.275V130.774L34.7318 142.034V138.531L18.4813 127.949V130.198L10.4176 126.423V117.461L42.7944 138.545V151.416L18.4807 140.156V143.29L34.7313 153.872V152.029L42.7944 155.878V164.36L10.4181 143.275Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M61.6609 161.07V155.833L85.6112 164.178V169.415L61.6609 161.07Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M104.358 185.272V176.311L113.724 179.986V182.235L132.241 186.585V184.703L125.207 179.88L116.989 177.95V172.713L125.207 174.644L132.241 173.124V171.244L113.724 166.894V169.143L104.358 168.419V159.458L141.608 168.206V178.348L133.39 179.183L141.608 183.879V194.02L104.358 185.272Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M162.992 198.026V171.179L191.346 191.526V181.754L188.248 181.284V176.048L200.858 177.962V203.777L192.804 202.553L172.504 187.671V194.235L175.602 194.705V199.942L162.992 198.026Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M207.132 204.55V178.736L245.229 182.681V208.495L207.132 204.55ZM216.702 200.304L235.659 202.267V186.926L216.702 184.963V200.304Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M249.683 188.319V183.083L262.194 183.841L272.643 201.55L283.019 185.104L293.138 185.718L277.242 210.569L267.897 210.001L255.166 188.652L249.683 188.319Z'
|
||||
fill='#2F1B5D'
|
||||
/>
|
||||
<path
|
||||
d='M326.036 212.885L334.629 200.477L335.095 199.804L334.524 199.216L323.852 188.271L328.549 187.878L339.79 199.409L330.734 212.493L326.036 212.885ZM324.031 214.051L331.283 213.443L341.072 199.302L328.931 186.848L321.925 187.435L321.81 187.601L333.812 199.911L324.025 214.046L324.031 214.051Z'
|
||||
fill='#D92ACE'
|
||||
/>
|
||||
<path
|
||||
d='M352.882 213.922L361.474 201.513L361.939 200.839L361.368 200.253L350.697 189.307L355.394 188.914L366.637 200.446L357.579 213.529L352.882 213.922ZM350.875 215.088L358.128 214.478L367.919 200.338L355.777 187.885L348.771 188.473L348.657 188.638L360.656 200.946L350.872 215.083L350.875 215.088Z'
|
||||
fill='#D92ACE'
|
||||
/>
|
||||
<path
|
||||
d='M378.256 214.32L386.847 201.911L387.313 201.238L386.742 200.651L376.07 189.704L380.767 189.312L392.01 200.843L382.953 213.925L378.256 214.32ZM376.248 215.485L383.502 214.877L393.292 200.736L381.15 188.284L374.144 188.87L374.03 189.035L386.031 201.345L376.244 215.481L376.248 215.485Z'
|
||||
fill='#D92ACE'
|
||||
/>
|
||||
<path
|
||||
d='M395.038 188.216L394.924 188.381L406.925 200.691L397.138 214.827L397.144 214.831L404.395 214.224L414.185 200.083L402.044 187.629L395.038 188.216Z'
|
||||
fill='#D92ACE'
|
||||
/>
|
||||
<path
|
||||
d='M414.462 186.724L414.347 186.89L426.348 199.199L416.561 213.336L416.566 213.34L423.817 212.732L433.607 198.591L421.466 186.139L414.462 186.724Z'
|
||||
fill='#D92ACE'
|
||||
/>
|
||||
<path
|
||||
d='M432.272 184.561L432.159 184.726L444.16 197.036L434.373 211.171L434.378 211.176L441.631 210.568L451.422 196.428L439.279 183.974L432.272 184.561Z'
|
||||
fill='#D92ACE'
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
export default function Circle({ className }) {
|
||||
return (
|
||||
<svg
|
||||
className={className}
|
||||
height='100%'
|
||||
viewBox='0 0 473 472'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<g filter='url(#filter0_d_181_191)'>
|
||||
<circle
|
||||
cx='236.5'
|
||||
cy='236'
|
||||
r='166'
|
||||
stroke='#2F1B5D'
|
||||
strokeWidth='40'
|
||||
shapeRendering='crispEdges'
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter
|
||||
id='filter0_d_181_191'
|
||||
x='0.5'
|
||||
y='0'
|
||||
width='472'
|
||||
height='472'
|
||||
filterUnits='userSpaceOnUse'
|
||||
colorInterpolationFilters='sRGB'
|
||||
>
|
||||
<feFlood floodOpacity='0' result='BackgroundImageFix' />
|
||||
<feColorMatrix
|
||||
in='SourceAlpha'
|
||||
type='matrix'
|
||||
values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'
|
||||
result='hardAlpha'
|
||||
/>
|
||||
<feOffset />
|
||||
<feGaussianBlur stdDeviation='25' />
|
||||
<feComposite in2='hardAlpha' operator='out' />
|
||||
<feColorMatrix
|
||||
type='matrix'
|
||||
values='0 0 0 0 0.773556 0 0 0 0 0.327778 0 0 0 0 0.983333 0 0 0 0.2 0'
|
||||
/>
|
||||
<feBlend
|
||||
mode='normal'
|
||||
in2='BackgroundImageFix'
|
||||
result='effect1_dropShadow_181_191'
|
||||
/>
|
||||
<feBlend
|
||||
mode='normal'
|
||||
in='SourceGraphic'
|
||||
in2='effect1_dropShadow_181_191'
|
||||
result='shape'
|
||||
/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
export default function Eye({ className }) {
|
||||
return (
|
||||
<svg
|
||||
className={className}
|
||||
height='100%'
|
||||
viewBox='0 0 485 337'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<g filter='url(#filter0_d_181_192)'>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M50.5 142.239L74.8397 114.72L137.533 175.709C142.269 171.883 147.703 167.864 153.643 163.805L113.659 110.353L136.834 94.3904L173.014 151.901C183.999 145.91 196.189 140.345 209.542 136.055L179.108 41.0538L225.187 30L244.247 128.286C251.545 127.475 258.882 127.049 266.257 127.088L283.26 47.1218L316.684 54.8518L292.849 129.562C318.12 134.161 339.199 144.906 356.085 158.394L420.952 79.3943L434.5 92.1874L367.498 168.366C380.891 181.468 390.984 196.116 397.777 209.992L356.202 233.916C356.202 233.916 339.354 194.532 307.639 170.801C311.288 179.149 313.267 188.387 313.267 198.049C313.267 236.003 282.173 267 244.092 267C203.991 267 172.237 232.756 175.032 193.218L210.396 197.469C205.622 214.978 218.976 233.066 237.803 233.066C253.331 233.066 266.219 220.388 266.219 204.774C266.219 163.226 218.781 153.061 184.892 167.361C163.813 176.289 146.849 189.391 123.635 207.209C99.9169 185.101 75.2279 163.844 50.5 142.239Z'
|
||||
fill='#5C46B2'
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter
|
||||
id='filter0_d_181_192'
|
||||
x='0.5'
|
||||
y='0'
|
||||
width='484'
|
||||
height='337'
|
||||
filterUnits='userSpaceOnUse'
|
||||
colorInterpolationFilters='sRGB'
|
||||
>
|
||||
<feFlood floodOpacity='0' result='BackgroundImageFix' />
|
||||
<feColorMatrix
|
||||
in='SourceAlpha'
|
||||
type='matrix'
|
||||
values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'
|
||||
result='hardAlpha'
|
||||
/>
|
||||
<feOffset dy='20' />
|
||||
<feGaussianBlur stdDeviation='25' />
|
||||
<feComposite in2='hardAlpha' operator='out' />
|
||||
<feColorMatrix
|
||||
type='matrix'
|
||||
values='0 0 0 0 0.546065 0 0 0 0 0.5375 0 0 0 0 1 0 0 0 0.2 0'
|
||||
/>
|
||||
<feBlend
|
||||
mode='normal'
|
||||
in2='BackgroundImageFix'
|
||||
result='effect1_dropShadow_181_192'
|
||||
/>
|
||||
<feBlend
|
||||
mode='normal'
|
||||
in='SourceGraphic'
|
||||
in2='effect1_dropShadow_181_192'
|
||||
result='shape'
|
||||
/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
export default function Logo({ className }) {
|
||||
return (
|
||||
<svg
|
||||
className={className}
|
||||
width='100%'
|
||||
height='100%'
|
||||
viewBox='0 0 293 182'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M0 86.1918L18.5717 65.0594L66.4078 111.895C70.0214 108.957 74.1682 105.87 78.7001 102.753L48.1916 61.7055L65.8746 49.4475L93.4804 93.6119C101.863 89.0114 111.163 84.7374 121.353 81.4429L98.1307 8.48858L133.29 0L147.833 75.4772C153.401 74.8539 159 74.5274 164.627 74.5571L177.601 13.1484L203.104 19.0845L184.917 76.4566C204.2 79.9886 220.283 88.2397 233.168 98.5982L282.663 37.9315L293 47.7557L241.876 106.256C252.095 116.317 259.796 127.566 264.98 138.221L233.257 156.594C233.257 156.594 220.402 126.349 196.202 108.126C198.986 114.537 200.497 121.63 200.497 129.05C200.497 158.196 176.772 182 147.714 182C117.117 182 92.888 155.703 95.0206 125.34L122.004 128.605C118.361 142.05 128.55 155.941 142.916 155.941C154.764 155.941 164.598 146.205 164.598 134.215C164.598 102.308 128.402 94.5023 102.544 105.484C86.4605 112.34 73.5166 122.402 55.8039 136.084C37.7061 119.107 18.8679 102.783 0 86.1918Z'
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
After Width: | Height: | Size: 6.1 KiB |
After Width: | Height: | Size: 6.1 KiB |
|
@ -1,15 +1,15 @@
|
|||
import { remark } from 'remark'
|
||||
import html from 'remark-html'
|
||||
import strip from 'strip-markdown'
|
||||
import { remark } from 'remark';
|
||||
import html from 'remark-html';
|
||||
import strip from 'strip-markdown';
|
||||
|
||||
export async function markdownToHtml(markdown) {
|
||||
const result = await remark().use(html).process(markdown)
|
||||
const result = await remark().use(html).process(markdown);
|
||||
|
||||
return result.toString()
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
export async function markdownToText(markdown) {
|
||||
const result = await remark().use(strip).process(markdown)
|
||||
const result = await remark().use(strip).process(markdown);
|
||||
|
||||
return result.toString()
|
||||
return result.toString();
|
||||
}
|
||||
|
|
|
@ -1,66 +1,67 @@
|
|||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import matter from 'gray-matter'
|
||||
import { markdownToHtml, markdownToText } from './markdown'
|
||||
import { cache } from 'react'
|
||||
import { i18n } from '../../i18n-config'
|
||||
import { cache } from 'react';
|
||||
|
||||
import { markdownToHtml, markdownToText } from './markdown';
|
||||
import { i18n } from '../../i18n-config';
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import matter from 'gray-matter';
|
||||
import process from 'process';
|
||||
|
||||
async function getTruncatedPostContent(content) {
|
||||
const words = content.split(' ')
|
||||
const truncatedWords = 9
|
||||
const words = content.split(' ');
|
||||
const truncatedWords = 9;
|
||||
const truncatedContent =
|
||||
words.length > truncatedWords
|
||||
? words.slice(0, truncatedWords).join(' ') + '...'
|
||||
: content
|
||||
const truncatedContentAsText = await markdownToText(truncatedContent)
|
||||
: content;
|
||||
const truncatedContentAsText = await markdownToText(truncatedContent);
|
||||
|
||||
return truncatedContentAsText
|
||||
return truncatedContentAsText;
|
||||
}
|
||||
|
||||
export const getSortedPostsData = cache(async (locale) => {
|
||||
const postsDirectory = path.join(process.cwd(), `src/posts/${locale}`)
|
||||
const fileNames = fs.readdirSync(postsDirectory)
|
||||
const postsDirectory = path.join(process.cwd(), `src/posts/${locale}`);
|
||||
const fileNames = fs.readdirSync(postsDirectory);
|
||||
|
||||
const allPostsDataPromises = fileNames.map(async (fileName) => {
|
||||
const id = fileName.replace(/\.md$/, '')
|
||||
const id = fileName.replace(/\.md$/, '');
|
||||
|
||||
const fullPath = path.join(postsDirectory, fileName)
|
||||
const fileContents = fs.readFileSync(fullPath, 'utf8')
|
||||
const fullPath = path.join(postsDirectory, fileName);
|
||||
const fileContents = fs.readFileSync(fullPath, 'utf8');
|
||||
|
||||
const matterResult = matter(fileContents)
|
||||
const content = matterResult.content
|
||||
const truncatedContent = await getTruncatedPostContent(content)
|
||||
const contentAsHtml = await markdownToHtml(content)
|
||||
const matterResult = matter(fileContents);
|
||||
const content = matterResult.content;
|
||||
const truncatedContent = await getTruncatedPostContent(content);
|
||||
const contentAsHtml = await markdownToHtml(content);
|
||||
|
||||
return {
|
||||
id,
|
||||
content: contentAsHtml,
|
||||
truncatedContent,
|
||||
...matterResult.data,
|
||||
}
|
||||
})
|
||||
const allPostsData = await Promise.all(allPostsDataPromises)
|
||||
};
|
||||
});
|
||||
const allPostsData = await Promise.all(allPostsDataPromises);
|
||||
|
||||
const sortedPostsData = allPostsData.sort((a, b) => {
|
||||
if (a.date < b.date) {
|
||||
return -1
|
||||
return -1;
|
||||
} else {
|
||||
return 1
|
||||
return 1;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
return {
|
||||
posts: sortedPostsData,
|
||||
}
|
||||
})
|
||||
return sortedPostsData;
|
||||
});
|
||||
|
||||
export const getAllPosts = cache(async () => {
|
||||
const allPosts = {}
|
||||
const allPosts = {};
|
||||
|
||||
for (const locale of i18n.locales) {
|
||||
const { posts } = await getSortedPostsData(locale)
|
||||
allPosts[locale] = posts
|
||||
const { posts } = await getSortedPostsData(locale);
|
||||
allPosts[locale] = posts;
|
||||
}
|
||||
|
||||
return allPosts
|
||||
})
|
||||
return allPosts;
|
||||
});
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { NextResponse } from "next/server";
|
||||
import type { NextRequest } from "next/server";
|
||||
import { NextResponse } from 'next/server';
|
||||
import type { NextRequest } from 'next/server';
|
||||
|
||||
import { i18n } from "../i18n-config";
|
||||
import { i18n } from '../i18n-config';
|
||||
|
||||
import { match as matchLocale } from "@formatjs/intl-localematcher";
|
||||
import Negotiator from "negotiator";
|
||||
import { match as matchLocale } from '@formatjs/intl-localematcher';
|
||||
import Negotiator from 'negotiator';
|
||||
|
||||
function getLocale(request: NextRequest): string | undefined {
|
||||
// Negotiator expects plain object so we need to transform headers
|
||||
|
@ -28,16 +28,17 @@ export function middleware(request: NextRequest) {
|
|||
const pathname = request.nextUrl.pathname;
|
||||
// `/_next/` and `/api/` are ignored by the watcher, but we need to ignore files in `public` manually.
|
||||
// If you have one
|
||||
if (
|
||||
[
|
||||
'/manifest.json',
|
||||
'/favicon.ico',
|
||||
'/next.svg',
|
||||
'/vercel.svg',
|
||||
// Your other files in `public`
|
||||
].includes(pathname)
|
||||
)
|
||||
return
|
||||
const paths = [
|
||||
'/manifest.json',
|
||||
'/favicon.ico',
|
||||
'/next.svg',
|
||||
'/vercel.svg',
|
||||
// Your other files in `public`
|
||||
];
|
||||
const dirs = ['/images/', '/posts/'];
|
||||
|
||||
if (paths.includes(pathname) || dirs.some((dir) => pathname.startsWith(dir)))
|
||||
return;
|
||||
|
||||
// Check if there is any supported locale in the pathname
|
||||
const pathnameIsMissingLocale = i18n.locales.every(
|
||||
|
@ -52,7 +53,7 @@ export function middleware(request: NextRequest) {
|
|||
// The new URL is now /en-US/products
|
||||
return NextResponse.redirect(
|
||||
new URL(
|
||||
`/${locale}${pathname.startsWith("/") ? "" : "/"}${pathname}`,
|
||||
`/${locale}${pathname.startsWith('/') ? '' : '/'}${pathname}`,
|
||||
request.url
|
||||
)
|
||||
);
|
||||
|
@ -61,5 +62,5 @@ export function middleware(request: NextRequest) {
|
|||
|
||||
export const config = {
|
||||
// Matcher ignoring `/_next/` and `/api/`
|
||||
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
|
||||
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
title: 'Bulgarian'
|
||||
date: '08-06-2024'
|
||||
imageUrl: '/posts/post-1.webp'
|
||||
---
|
||||
|
||||
**Some** description
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
title: 'English'
|
||||
date: '08-06-2024'
|
||||
imageUrl: '/posts/post-1.webp'
|
||||
---
|
||||
|
||||
**Some** description
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css');
|
||||
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap');
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
.container {
|
||||
@apply mx-auto w-full max-w-screen-xl px-6 py-8 sm:px-12 sm:py-10;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
p {
|
||||
@apply text-black;
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.fa-color-custom {
|
||||
color: #000;
|
||||
}
|
||||
.fa-color-custom:hover {
|
||||
color: red;
|
||||
}
|
||||
}
|
|
@ -1,24 +1,26 @@
|
|||
import type { Config } from 'tailwindcss'
|
||||
import type { Config } from 'tailwindcss';
|
||||
|
||||
const config: Config = {
|
||||
content: [
|
||||
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
],
|
||||
content: ['./src/**/*.{js,ts,jsx,tsx}'],
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
openSans: ['Open Sans', 'sans-serif'],
|
||||
},
|
||||
backgroundImage: {
|
||||
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
|
||||
'gradient-conic':
|
||||
'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
|
||||
'home-bg': "url('/images/openfest-1.png')",
|
||||
},
|
||||
colors: {
|
||||
'dark-blue': '#09021B',
|
||||
'deep-blue': '#0F0429',
|
||||
blue: '#2F1B5D',
|
||||
'neon-green': '#34EAD8',
|
||||
'neon-pink': '#D92ACE',
|
||||
'blue-2': '#004394',
|
||||
'blue-8': '#E2EFFE',
|
||||
//'dark-blue': '#09021B',
|
||||
//'deep-blue': '#0F0429',
|
||||
//blue: '#2F1B5D',
|
||||
//'neon-green': '#34EAD8',
|
||||
//'neon-pink': '#D92ACE',
|
||||
},
|
||||
letterSpacing: {
|
||||
max: '0.3em',
|
||||
|
@ -32,5 +34,6 @@ const config: Config = {
|
|||
},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
export default config
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
}
|
||||
],
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
"@/*": ["./src/*"],
|
||||
"@/dictionaries": ["./dictionaries"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
|
|